MySql學習(二) —— where / having / group by / order by / limit 簡單查詢


注:該MySql系列博客僅為個人學習筆記。

 

這篇博客主要記錄sql的五種子句查詢語法!

 

一個重要的概念:將字段當做變量看,無論是條件,還是函數,或者查出來的字段。

select五種子句

  where 條件查詢

  group by 分組

  having 篩選

  order by 排序

  limit 限制結果條數

 

 為了練習上面5種子句,先建立一張goods表,主要用於查詢操作,表結構如下:

    

  所有數據:

  

 

1.基礎查詢 —— where

where常用運算符

 

1.1 查出主鍵為20的商品

  :mysql> SELECT goods_id,cat_id,goods_sn,goods_name,goods_number,is_hot FROM goods WHERE goods_id = 20;

  

1.2 查出不屬於第三類的所有商品

  :mysql> SELECT goods_id,cat_id,goods_sn,goods_name,click_count,is_best FROM goods WHERE cat_id != 3;

   

  :mysql> SELECT goods_id,cat_id,goods_sn,goods_name,click_count,is_best FROM goods WHERE cat_id <> 3;

  

1.3 查詢高於3000元的商品

   :mysql> SELECT goods_id,cat_id,goods_name,shop_price,is_new FROM goods WHERE shop_price > 3000;

   

1.4 查詢低於或等於100元的商品

   :mysql> SELECT goods_id,goods_name,goods_number,shop_price FROM goods WHERE shop_price <= 100;

   

1.5 取出第4類和第11類的商品

  :mysql> SELECT cat_id,goods_name,shop_price FROM goods WHERE cat_id IN (4,11);

  

1.6 取出不在第3類和第11類的商品

  :mysql> SELECT goods_id,cat_id,goods_name FROM goods WHERE cat_id != 3 && cat_id != 11;

  

  not in 方式實現

  :mysql> SELECT goods_id,cat_id,goods_name FROM goods WHERE cat_id NOT IN (3,11);

  

1.7 取出 100 <= 價格 <= 500 的商品

  :mysql> SELECT goods_id,cat_id,goods_name,shop_price FROM goods WHERE shop_price >= 100 && shop_price <= 500;

  

  使用between,可以看出是包括邊界值的

  :mysql> SELECT goods_id,cat_id,goods_name,shop_price FROM goods WHERE shop_price between 100 AND 500;

  

1.8  取出價格大於100且小於300,或者大於3000且小於5000的商品

  :mysql> SELECT goods_id,cat_id,goods_name,shop_price

      -> FROM goods

      -> WHERE shop_price > 100 AND shop_price < 300

      -> OR shop_price > 3000 AND shop_price < 5000;

  

  取出價格大於100且小於300,或者大於4000且小於5000的商品

  :mysql> SELECT goods_id,goods_name,shop_price FROM goods WHERE shop_price between 100 AND 300 OR shop_price between 4000 AND 5000;

  

 

like模糊查詢

1.9 查出以"諾基亞"開頭的商品; "%"通配任意字符

  :mysql> SELECT goods_id,goods_name,goods_sn,shop_price FROM goods WHERE goods_name LIKE "諾基亞%";

  

1.10 取出以"諾基亞N"開頭,且后面有兩個字符的商品;  "_"通配單一字符

  :mysql> SELECT goods_id,goods_name,shop_price FROM goods WHERE goods_name LIKE "諾基亞N__";

  

1.11 取出第三個欄目下面價格在1000到3000之間,並且點擊量 > 5 "諾基亞"開頭的系列商品

   :mysql> SELECT goods_id,goods_name,click_count,shop_price FROM goods WHERE shop_price BETWEEN 1000 AND 3000 AND click_count > 5 AND goods_name LIKE "諾基亞%";

  

1.12 取出本店價格比市場價格省的錢

  :mysql> SELECT goods_name AS '商品名', shop_price AS '本店價格', market_price AS '市場價格', market_price - shop_price AS '省錢' FROM goods WHERE goods_name LIKE "諾基亞%"

  

1.13 取出省錢200以上的商品;注意where后還是用的運算表達式。

  :mysql> SELECT goods_name AS name, shop_price AS shopPrice, market_price AS marketPrice, (market_price-shop_price) AS discount FROM goods WHERE (market_price-shop_price) >= 200;

  

  ## where后面不能直接用別名進行表達式判斷,會報錯,因為where查詢是根據表中字段進行查詢;查詢出來的是一個結果集(可以包含表中沒有的字段),如果想對結果集再篩選,可以用having篩選!

  :mysql> SELECT goods_name AS '商品名', shop_price AS '本店價格', market_price AS '市場價格', market_price - shop_price AS '省錢' FROM goods WHERE discount >= 200; 錯誤!

  

  #having再次篩選 

  :mysql> SELECT goods_name AS name, shop_price AS shopPrice, market_price AS marketPrice, (market_price - shop_price) AS discount FROM goods having discount >= 200;

  

 

2. group by 與 統計函數

  max:求最大

  min:求最小

  sum:求和

  avg:求平均

  count: 求總行數

 

2.1  查出最貴的商品

  :mysql> SELECT max(shop_price) FROM goods;

  

2.2. 查出最便宜的商品價格

  :mysql> SELECT min(shop_price) FROM goods;

  

2.3 查詢總庫存量

  :mysql> SELECT sum(goods_number) FROM goods;

  

2.4 查看所有商品的平均價格

  :mysql> SELECT avg(shop_price) FROM goods;

  

2.5 統計共有多少個商品

  :mysql> SELECT count(1) FROM goods;

  

  :mysql> select count(name) from test1;

   如果count()的字段為NULL是不會計數的

   

  :mysql> select count(*) from test1;

  

  select count(*) 查詢的是絕對的行數,就算某行全為NULL,也計算在內。

  select count(列名) 查詢的是該列不為NULL的所有行的行數。

  count(*)和count(1)的區別:對於MyIsam引擎的表,是沒有區別的,這種引擎內部有一計數器在維護着行數;如果是InnoDB的表,用count(*) 直接讀行數,效率很低,因為會一行行數!

 

2.6 查詢第三類下商品總數

  :mysql> select sum(goods_number) from goods where cat_id = 3;

  

2.7 查詢每個類別下的商品總量

  :mysql> SELECT cat_id, sum(goods_number) FROM goods GROUP BY cat_id;

     group by 有多少個類別,就有多少行

  

   :mysql> SELECT sum(goods_number) FROM goods GROUP BY cat_id;

    

  

  對於SQL標准來說,下面兩個語句是錯誤的,不能執行。但是在MySql中可以這么干。只是默認查出第一個值而已,但是並沒能一一對應。出於可移植性和規范性,不推薦這樣寫!

  嚴格來說,使用group by a,b,c 時,則select查詢的列,只能在a,b,c里選擇,語義上才沒有矛盾,才能一一對應起來!!!

  :mysql> SELECT goods_id, sum(goods_number) FROM goods;(非SQL標准)

  

    :mysql> SELECT goods_name, sum(goods_number), cat_id FROM goods GROUP BY cat_id; (非SQL標准)

    

2.8 查詢每個類別下商品的平均價格

  :mysql> SELECT cat_id, avg(shop_price) FROM goods GROUP BY cat_id;

  

 

3. having

3.1 查詢每個商品所積壓的貨款

  :mysql> SELECT goods_id,goods_name,goods_number,shop_price, (goods_number * shop_price) AS 'total_price' FROM goods;

  

3.2 查詢積壓的總貨款

  :mysql> SELECT SUM(goods_number * shop_price) AS '總貨款' FROM goods;

  

3.3 查詢每個類別下積壓的貨款

  :mysql> SELECT cat_id, SUM(goods_number * shop_price) AS 'total_money' FROM goods GROUP BY cat_id;

  

3.4 查詢某個類別下積壓的貨款大於20000的

  :mysql> SELECT cat_id, SUM(goods_number * shop_price) AS 'total_money' FROM goods GROUP BY cat_id HAVING total_money >= 20000;

  

3.5 查詢比市場價省200以上的商品,以及該商品所省的錢

  :mysql> SELECT goods_name,market_price,shop_price, (market_price - shop_price) AS 'price' FROM goods WHERE (market_price - shop_price) >= 200;

  where方式造成計算浪費,所以可以使用having進行結果集篩選。

  

  :mysql> SELECT goods_name,market_price,shop_price, (market_price - shop_price) AS 'price' FROM goods HAVING price >= 200;

  

 

4.where + group by + having + 函數 綜合查詢

  練習表:

  

 

4.1 查詢出兩門及兩門以上不及格者的平均成績(注意是所有科目的平均成績)

  :mysql> SELECT name, avg(score) FROM stu WHERE score < 60 GROUP BY name having count(1) >= 2; 錯誤!

  

  :mysql> SELECT name,avg(score),count(score<60) AS 'count' FROM stu GROUP BY name HAVING count >= 2;錯誤!

  count(a),無論a是什么,都只是數一行;count時,每遇到一行,就數一個a,跟條件無關!

  

  :mysql> SELECT name,avg(score), sum(score<60) as 'gk' FROM stu GROUP BY name having gk >= 2;

  解析:count(score<60)達不到想要的結果,並不是條件的問題,而是無論count()里的表達式是什么都會數一行。

    score<60 返回 1 或 0;所以可以用sum(score<60)來計算不及格的科目數!

  

  sum()和count()在某種程度上可以互換。

  

 

5. order by + limit

5.1 取出第四類的商品,並按價格由高到低

  :mysql> SELECT goods_name,cat_id,shop_price FROM goods WHERE cat_id = 4 ORDER BY shop_price DESC;

  order by(排序) 是針對最終結果集,所以order by 要放在where/group by/having 后面。降序:desc; 升序:asc.

  

5.2 按類別升序排列,同一類別下的商品按價格降序排列

  :mysql> SELECT goods_name,cat_id,shop_price FROM goods GROUP BY cat_id ORDER BY cat_id ASC,shop_price DESC;

  若有多個列需要排序,首先按第一個排序,再按后面的列排序

  

5.3 按類別降序排列,同一類別下的商品按價格升序排列(使用別名)

  :mysql> SELECT goods_name AS 'name', cat_id AS 'catId', shop_price AS 'price' FROM goods GROUP BY catId ORDER BY catId DESC, shop_price ASC;

  order by 查詢是針對結果集查詢的。

  

5.4 查詢前10數據

  :mysql> SELECT goods_id,goods_name,cat_id,shop_price FROM goods LIMIT 10;

  limit放在最后,用於限制查出的記錄數。

  

5.5 查詢價格最高的前三件商品

  :mysql> SELECT goods_name,cat_id,goods_number,shop_price FROM goods ORDER BY shop_price DESC LIMIT 3;

  

5.6 取出價格最高的前3至5件商品

  :mysql> SELECT goods_name,cat_id,goods_number,shop_price FROM goods ORDER BY shop_price DESC LIMIT 2,3;

   

 

 

 

 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 五種子句總結:

  1.select a,b,c from table where x = 1;  ==》》 where條件的 變量x 必須在表中存在;where是針對表做操作

 

  2.select a, b, c AS x having x = 1; ==》》 having 后的變量 x 可以是表中的列,也可以是別名,having是對查詢結果集進行再篩選。這點區別於where,如果where使用別名,則會報"unknown column"錯誤;having是針對結果集做操作

  

  3.select count(*) 查詢的是絕對的行數,就算某行全為NULL,也計算在內。

     select count(列名) 查詢的是該列不為NULL的所有行的行數。

     count(*)和count(1)的區別:對於MyIsam引擎的表,是沒有區別的,這種引擎內部有一計數器在維護着行數;如果是InnoDB的表,用count(*) 直接讀行數,效率很低,因為會一行行數!

   count(a<60),a<60返回值要么為1,要么為0,所以count()都會數一行,達不到根據條件數行數的目的;換一種思維,如果想計算a<60的行數,可以用sum(a < 60),滿足a<60的返回 1,不滿足返回 0。

   sum()在某種程度上可以替換count()!

  

  4.group by 有多少個類別,查出來就有多少行數據。

   group by是針對where查詢的結果集做操作!

     使用group by a,b,c 時,則select查詢的列,只能在a,b,c里選擇,語義上才沒有矛盾,才能一一對應起來。

   group by a desc:這是一種錯誤的寫法,group by 是沒有排序功能的。

   

  5.order by 是針對最終結果集進行排序的!所以放在where/group by/having 后面。降序:DESC; 升序:ASC。

   若有多個列需要排序,首先按第一個排序,再按后面的列排序;多個列排序用","隔開。

 

  6.limit [offset,] N :offset 偏移量,如果不寫則為0(從0開始);N取出條目;

 

  7.where是針對表做操作;having / group by / order by / limit 是針對結果集做操作,且先后順序固定;where查詢列只能是表字段,其余的查詢列既可以是表字段,也可以是別名。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM