mysql的查询、子查询及连接查询(商城查询常用)
?
一、mysql查詢的五種子句
where(條件查詢)、having(篩選)、group by(分組)、order by(排序)、limit(限制結果數) 1、where常用運算符: 比較運算符 > , ?< ,= ?, != (< >),>= ? , ? <= ? in(v1,v2..vn) ? [sql]? view plain copy print ?between v1 and v2 ? ?在v1至v2之間 (包含v1,v2) 邏輯運算符 not ( ! ) ?邏輯非 or ( || ) ? ?邏輯或 and ( && ) ?邏輯與 where price>=3000 and price <= 5000 or price >=500 and price <=1000? 取500-1000或者3000-5000的值 where price not between 3000 and 5000 不在3000與5000之間的值 模糊查詢 like 像 通配符: % ?任意字符 _ ? 單個字符 where goods_name like '諾基亞%' where goods_name like '諾基亞N__' ? ??(必須要兩個字符 ‘諾基亞N85’ ,諾基亞N9 就不行) 要匹配一個、兩個字符的話不嫌麻煩的要OR把 2、group by 分組 例子 aa表 a b123 10123 121234 111234 14 首先 group 是用來分組的 不是過濾重復項的。重復項刪除語句 DISTINCT用這個 。 select DISTINCT(a) from aa 結果就是 a1231234group by用來分組的 select a, sum(b) from aa group by a sum意思是總和。結果就是a b123 221234 25 語句的目的是以a為目標 需要知道 相同名字的物品 在b列一共有多少數量總和 select a,count(b) from aa group by a count 意思行數總和 結果就是a b123 21234 2 語句目的是 相同名字的物品 一共有幾行
?
(1)max:求最大值 select max(goods_price) from goods 這里會取出最大的價格的值,只有值 #查詢每個欄目下價格最高的 select cat_id,max(goods_price) from goos group by cat_id; #查出價格最高的商品編號 select goods_id,max(goods_price) from goods group by goods_id; (2)min:求最小值 (3)sum:求總數和 #求商品庫存總和 select sum(goods_number) from goods; (4)avg:求平均值 #求每個欄目的商品平均價格 select cat_id,avg(goods_price) from goods group by cat_id; (5)count:求總行數 #求每個欄目下商品種類 select cat_id,count(*) from goods group by cat_id;?
以ustuid為目標 統計apply表里每個ustuid有多少記錄(用group by ?結果有排序的效果(如下ustuid))
?
[sql]? view plain copy print ??
?
?
? ? ? ? ? ? ? ? ? ?### 要把每個字段名當成變量來理解,它可以進行運算### 例:查詢本店每個商品價格比市場價低多少; select goods_id,goods_name,goods_price-market_price from goods; 查詢每個欄目下面積壓的貨款 select cat_id,sum(goods_price*goods_number) from goods group by cat_id; ###可以用as來給計算結果取個別名### select cat_id,sum(goods_price * goods_number) ?as hk from goods group by cat_id 不僅列名可以取別名,表單也可以取別名
?
3、having 與where 的異同點 having與where類似,可以篩選數據,where后的表達式怎么寫,having后就怎么寫 where針對表中的列發揮作用, 查詢數據 having對查詢結果中的列發揮作用, 篩選數據 [sql]? view plain copy print ?感覺就像是score 換了一個名字? ? 所以大概明白 having 就是把 前面一個表達式換了一個代號 有時候where 后面不能用 表達式的時候 //這里不能用where因為s是查詢結果,而where只能對表中的字段名篩選 如果用where的話則是: select goods_id,goods_name from goods where market_price - shop_price > 200; #同時使用where與having select cat_id,goods_name,market_price - shop_price as s from goods where cat_id = 3 having s > 200; #查詢積壓貨款超過2萬元的欄目,以及該欄目積壓的貨款 select cat_id,sum(shop_price * goods_number) as t from goods group by cat_id having s > 20000 ?#查詢兩門及兩門以上科目不及格的學生的平均分(stu表) 思路: #先計算所有學生的平均分 select name,avg(score) as pj from stu group by name; #查出所有學生的掛科情況 select name,score<60 from stu; #這里score<60是判斷語句,所以結果為真或假,mysql中真為1假為0 #查出兩門及兩門以上不及格的學生 select name,sum(score<60) as gk from stu group by name having gk > 1; #綜合結果 select name,sum(score<60) as gk,avg(score) as pj from stu group by name having gk >1;
?
4、order by (1) order by price ?//默認升序排列 (2)order by price desc //降序排列 (3)order by price asc //升序排列,與默認一樣 (4)order by rand() //隨機排列,效率不高 #按欄目號升序排列,每個欄目下的商品價格降序排列 select * from goods where cat_id !=2 order by cat_id,price desc; 如果是多個排序條件的 : [sql]? view plain copy print ?5、limit 在我們使用查詢語句的時候,經常要返回前幾條或者中間某幾行數據,這個時候怎么辦呢?不用擔心, mysql已經為我們提供了這樣一個功能。 SELECT?*?FROM?table??LIMIT?[offset,]?rows?|?rows?OFFSET?offset
LIMIT 子句可以被用于強制 SELECT 語句返回指定的記錄數。LIMIT 接受一個或兩個數字參數。參數必須是一個整數常量。如果給定兩個參數,第一個參數指定第一個返回記錄行的偏移量,第二個參數指定返回記錄行的最大數目。初始記錄行的偏移量是 0(而不是 1): 為了與 PostgreSQL 兼容,MySQL 也支持句法: LIMIT # OFFSET #。?
//為了檢索從某一個偏移量到記錄集的結束所有的記錄行,可以指定第二個參數為?- 1:?
mysql>?SELECT?*?FROM?table?LIMIT? 95,- 1;?//?檢索記錄行? 96-last.
//如果只給定一個參數,它表示返回最大的記錄行數目:?
mysql>?SELECT?*?FROM?table?LIMIT? 5;?????//檢索前? 5?個記錄行
//換句話說,LIMIT?n?等價于?LIMIT? 0,n。 ###查詢每個欄目下最貴的商品 思路: #先對每個欄目下的商品價格排序 select cat_id,goods_id,goods_name,shop_price from goods order by cat_id,shop_price desc; #上面的查詢結果中每個欄目的第一行的商品就是最貴的商品 #把上面的查詢結果理解為一個臨時表[存在于內存中]【子查詢】 #再從臨時表中選出每個欄目最貴的商品 select * from (select goods_id,goods_name,cat_id,shop_price from goods order by cat_id,shop_price desc)?as t ?group by cat_id; ? ? ? ? ? ? ?as t 作為臨時表 這個語句不能缺 #這里使用group by cat_id是因為臨時表中每個欄目的第一個商品就是最貴的商品,而group by前面沒有使用聚合函數,所以默認就取每個分組的第一行數據,這里以cat_id分組 良好的理解模型: 1、where后面的表達式,把表達式放在每一行中,看是否成立 2、字段(列),理解為變量,可以進行運算(算術運算和邏輯運算) ? 3、 取出結果可以理解成一張臨時表 二、mysql子查詢 1、where型子查詢 (把內層查詢結果當作外層查詢的比較條件) #不用order by 來查詢最新的商品 select goods_id,goods_name from goods where goods_id = (select max(goods_id) from goods); #取出每個欄目下最新的產品(goods_id唯一) select cat_id,goods_id,goods_name from goods where goods_id in( select max(goods_id) from goods group by cat_id); 2、from型子查詢 (把內層的查詢結果供外層再次查詢) #用子查詢查出掛科兩門及以上的同學的平均成績 思路: #先查出哪些同學掛科兩門以上 select name,count(*) as gk from stu where score < 60 having gk >=2; #以上查詢結果,我們只要名字就可以了,所以再取一次名字 select name from (select name,count(*) as gk from stu having gk >=2) as t; #找出這些同學了,那么再計算他們的平均分 select name,avg(score) from stu where name in (select name from (select name,count(*) as gk from stu having gk >=2) as t) group by name; 3、exists型子查詢 (把外層查詢結果拿到內層,看內層的查詢是否成立) #查詢哪些欄目下有商品,欄目表category,商品表goods select cat_id,cat_name from category where exists(select * from goods where goods.cat_id = category.cat_id);
查詢 哪些 用戶(user)有 申請記錄(apply)
注:可以用【 表名.字段名】來表示
如下面的sql語句也可以這樣下
?
[sql]? view plain copy print ??
?
[sql]? view plain copy print ??
UNION在進行表鏈接后會篩選掉重復的記錄,所以在表鏈接后會對所產生的結果集進行排序運算,刪除重復的記錄再返回結果。
舉例說明:
[sql]? view plain copy print ?這個SQL在運行時先取出兩個表的結果,再用排序空間進行排序刪除重復的記錄,最后返回結果集,如果表數據量大的話可能會導致用磁盤進行排序。??
?
MySQL中的UNION ALL
UNION ALL只是簡單的將兩個結果合并后就返回。這樣,如果返回的兩個結果集中有重復的數據,那么返回的結果集就會包含重復的數據了。
舉例說明:
[sql]? view plain copy print ?注: 使用 UNION 時 前一個 select column的個數要等于后一個select column的個數
如:
?
[sql]? view plain copy print ??
?
如果現在使用:
?
[sql]? view plain copy print ??
則是不會成功的, 數據庫為報:?
ErrorThe used SELECT statements have a different number of columns
?
這是提示查詢的兩張表的字段不統一,如果table1比table2的字段內容多,可以使用空字符串來代替
?
[sql]? view plain copy print ??
如果里面有不想要的,千萬要記住前面查詢內容要和后面查詢內容的字段個數要一樣,前面你查詢4個,后面也要相應的放4個,這樣就不會提示參數數量不同的錯誤了。
?
其實稍稍修改一下就可以了
對于 'select id,createDate,desc,hasCode from table1' 可以任意選擇4個field
?
從效率上說,UNION ALL 要比UNION快很多,所以,如果可以確認合并的兩個結果集中不包含重復的數據的話,那么就使用UNION ALL。
?
如果遇到兩張表數據不同來集合查詢,可以使用union all這個函數進行操作
?
[sql]? view plain copy print ??
這是查詢結果集共有多少條數據,
如果還有查詢條件,直接在c后面添加就可以,比如按照時間進行查詢
?
[sql]? view plain copy print ??
這里強調一下,你要按照什么樣的條件進行查詢時,要分別在select子查詢中添加上條件,最后在按照統一的時間倒序或者正序
注:?缺省的情況下,UNION 子句不返回重復的記錄.如果想顯示所有記錄,可以加ALL選項?
UNION運算要求查詢具有相同數目的字段.但是,字段數據類型不必相同.?
四、左連接,右連接,內連接
?
現有表a有10條數據,表b有8條數據,那么表a與表b的笛爾卡積是多少? select * from ta,tb ? //輸出結果為8*10=80條 1、左連接 以左表為準,去右表找數據,如果沒有匹配的數據,則以null補空位,所以輸出結果數>=左表原數據數 語法:select n1,n2,n3 from ta?left join?tb?on?ta.n1= ta.n2 [ 這里on后面的表達式,不一定為=,也可以>,<等算術、邏輯運算符]【連接完成后,可以當成一張新表來看待,運用where等查詢】 下面是例子分析表A記錄如下:?
aID????????aNum?
1???????????a20050111?
2???????????a20050112?
3???????????a20050113?
4???????????a20050114?
5???????????a20050115?
表B記錄如下:?
bID????????bName?
1????????????2006032401?
2???????????2006032402?
3???????????2006032403?
4???????????2006032404?
8???????????2006032408?
創建這兩個表SQL語句如下:?
CREATE?TABLE??a?
aID?int(?1?)?AUTO_INCREMENT?PRIMARY?KEY?,?
aNum?char(?20?)?
)?
CREATE?TABLE?b(?
bID?int(?1?)?NOT?NULL?AUTO_INCREMENT?PRIMARY?KEY?,?
bName?char(?20?)??
)?
INSERT?INTO?a?
VALUES?(?1,?'a20050111'?)?,?(?2,?'a20050112'?)?,?(?3,?'a20050113'?)?,?(?4,?'a20050114'?)?,?(?5,?'a20050115'?)?;?
INSERT?INTO?b?
VALUES?(?1,?'?2006032401'?)?,?(?2,?'2006032402'?)?,?(?3,?'2006032403'?)?,?(?4,?'2006032404'?)?,?(?8,?'2006032408'?)?;?
實驗如下:?
1.left?join(左聯接)?
sql語句如下:??
SELECT?*?FROM?a?
LEFT?JOIN??b??
ON?a.aID?=b.bID?
結果如下:?
aID????????aNum???????????????????bID???????????bName?
1????????????a20050111?????????1???????????????2006032401?
2????????????a20050112?????????2??????????????2006032402?
3????????????a20050113?????????3??????????????2006032403?
4????????????a20050114?????????4??????????????2006032404?
5????????????a20050115?????????NULL???????NULL?
(所影響的行數為?5?行)?
結果說明:?
????????left?join是以A表的記錄為基礎的,A可以看成左表,B可以看成右表,left?join是以左表為準的.?
換句話說,左表(A)的記錄將會全部表示出來,而右表(B)只會顯示符合搜索條件的記錄(例子中為:?A.aID?=?B.bID).?
B表記錄不足的地方均為NULL.? 2、右連接 a left join b 等價于 b right join a 推薦使用左連接代替右連接 語法:select n1,n2,n3 from ta?right join?tb?on?ta.n1= ta.n2 3.inner?join(相等聯接或內聯接)?
sql語句如下:??
SELECT?*?FROM??a?
INNER?JOIN??b?
ON?a.aID?=b.bID?
等同于以下SQL句:?
SELECT?*??
FROM?a,b?
WHERE?a.aID?=?b.bID?
結果如下:?
aID????????aNum???????????????????bID???????????bName?
1????????????a20050111?????????1???????????????2006032401?
2????????????a20050112?????????2??????????????2006032402?
3????????????a20050113?????????3??????????????2006032403?
4????????????a20050114?????????4??????????????2006032404?
結果說明:?
????????很明顯,這里只顯示出了?A.aID?=?B.bID的記錄.這說明inner?join并不以誰為基礎,它只顯示符合條件的記錄.?
LEFT?JOIN操作用于在任何的?FROM?子句中,?
組合來源表的記錄。使用?LEFT?JOIN?運算來創建一個左邊外部聯接。左邊外部聯接將包含了從第一個(左邊)開始的兩個表中的全部記錄,即?
使在第二個(右邊)表中并沒有相符值的記錄。??
語法:FROM?table1?LEFT?JOIN?table2?ON?table1.field1?compopr?table2.field2??
說明:table1,?table2參數用于指定要將記錄組合的表的名稱。?
field1,?field2參數指定被聯接的字段的名稱。且這些字段必須有相同的數據類型及包含相同類型的數據,但它們不需要有相同的?
名稱。?
compopr參數指定關系比較運算符:"=",?"<",?">",?"<=",?">="?或?"<>"。?
如果在INNER?JOIN操作中要聯接包含Memo?數據類型或?OLE?Object?數據類型數據的字段,將會發生錯誤。
轉載于:https://www.cnblogs.com/zhangzhaoyang/p/7741167.html
總結
以上是生活随笔為你收集整理的mysql的查询、子查询及连接查询(商城查询常用)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿强《HI-FI最强音》[DTS-WAV
- 下一篇: MySQL相关基础知识