mysql-sql案例

//利用主鍵索引使用內連接 好於limit
select * FROM product p JOIN  (SELECT id FROM product WHERE id > 500 LIMIT 10) tmp ON p.id = tmp.id;
//update 1
update 第一條 也可以用limit 1
//更新自己
update table set a = a + 1,b = b + 1;

//查詢自己 更新自己
#1093 - You can't specify target table 'tab1' for update in FROM clause
update tab1 SET NAME = '333' WHERE id in (SELECT id FROM tab1)//報錯
#1,將以下查詢結果作爲中間表,
SELECT id FROM tab1
#2,再查詢一遍中間表作爲結果集
SELECT t1.id FROM (SELECT id FROM tab1) t1
#更新
update tab1 SET NAME = '333' WHERE id in (SELECT t1.id FROM (SELECT id FROM tab1) t1);

//查詢某一pid下 最小的id的數據
select * from t_sys_china a where a.p_id = '150000';
select `NO` FROM t_sys_china a WHERE a.p_id = '150000'; -- 全表掃描 mysql的確定最後的數據是否爲150000
EXPLAIN select MIN(`NO`) FROM t_sys_china a WHERE a.p_id = '150000';-- 這樣查詢全表掃描 min()要把所有數據都比較過才能確定最小
# 解決 :強制使用主鍵索引 使用索引查詢不使用order by 也是有序的
EXPLAIN select * from t_sys_china a USE INDEX(PRIMARY)  where a.p_id = '150000' ;

//COUNT() 大於多少 可以 用2個 count 小於 相減 來得到結果,select(*) 是有緩存的,其查詢速度非常快
select count(*) - (select count(*) where id < 100)   ;

//#group by 分組用於統計,而不是篩選數據 -- 有索引,group by 會避免臨時表
//#A,B兩表連接,主要查詢A表列,GROUP BY,ORDER BY 的列儘量相同,而且應該顯示爲A列
//#union 優化 union all 不過濾 建議放在程序中過濾

//使用變量
eg:
set @age:=20;
select @age;
set @age := @age+100;
select @age;

1.計算排名 原理:2個數利用中間數進行比較,並不斷遞增
set @pres:=0,@currs:=0,@rank:=0;
select `name`,(@currs:=price) AS price,
@rank:=if(@currs<>@pres,@rank:=@rank+1,@rank) as rank,
@pres:=price as prev
 from product ORDER BY price DESC;
 
2.如果在1號表裏面查找到了 就不去2號表了
SET @find:=0;
select id,name,@find:=1 FROM product
UNION
select id,name,1 from B WHERE id =xx and @find <> 1
UNION
select 1,1,@find:=0 from product where 0;
3.row_numer
SELECT @rowno:=@rowno+1 as rowno,
r.*
from t_project r ,(select @rowno:=0) t;

4.查詢並獲得行id,用於查詢並添加中
SELECT @rowno:=@rowno+1 as rowno,
p.*
CONCAT(p.p_name,@rowno)
from
(select * from t_project) p ,
(select @rowno:=0) t;
5.根據某字段分組並遞增排序
select rank, result.*
    from (  
        select B.*,
            @rownum:=@rownum+1 ,  
            if(@pdept=B.XXXXXX, @rank:=@rank+1,@rank:=1) as rank,  
            @pdept:=B.XXXXXX  
        from  B , (select @rownum :=0 , @pdept := null ,@rank:=0) a  
    ) result


//2.統計AAA表中 總數 和某一狀態的 個數
select
COUNT(a.XXX)
,COUNT(b.XXX)
from AAA a
LEFT JOIN (select PRJ_ID FROM AAA WHERE 某個狀態 = '1' ) b
ON  a.XX = b.XX #自己關聯自己
GROUP BY a.XXX

//3.先聚合,在關聯,防止(出現以字表多條)  PPP與EEE是1:n EEE中有PPP的pid
select  sum(b.num)
    from PPP p    LEFT JOIN (
                        SELECT e.pID,sum(e.EQU_NUM) as total FROM EEE e
                        WHERE     e.column = '1'
                        GROUP BY e.pID
                        ) a ON p.pID = e.pID
    WHERE 1=1
    GROUP BY p.column  

//通過最大時間過濾1
ORDER BY r.DATA_DATE DESC LIMIT 1
//通過最大時間過濾2
SELECT t.ORDER_ID,t.time FROM table t WHERE t.time in (
    SELECT MAX(a.time)
        FROM table2 a GROUP BY a.AA,a.BB HAVING MAX(a.time) )


//in與exists   
1.in 型子查詢陷阱              
select * from A where  colum  in (select ids from B whre b.col = xx)
執行原理:     此時索引發揮作用 ,並不是先查詢in裏面的sql語句 而是
              從上至下掃描主表,判斷是否滿足主從表關係查詢,查詢效率非常低
              mysql的查詢優化器將in 優化爲了exists的執行效果,所以當主表特別大時,從上到下非常慢
              解決 改成 join
              
2.exists和inner join 哪個快?  不一定,創建臨時表的一定要排除
select c.cat_id,c.cat_name from category c join goods g
on c.cat_id=g.cat_id group by cat_id;

select c.cat_id,c.cat_name from category c
where exists (select * from goods g where g.cat_id c.cat_id);

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章