mysql联合子查询_2020-09-08MySQL多表联合查询之子查询
一、子查詢(xún) in
1:子查詢(xún)是將一個(gè)查詢(xún)語(yǔ)句嵌套在另一個(gè)查詢(xún)語(yǔ)句中。
2:內(nèi)層查詢(xún)語(yǔ)句的查詢(xún)結(jié)果,可以為外層查詢(xún)語(yǔ)句提供查詢(xún)條件。
3:子查詢(xún)中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等關(guān)鍵字
4:還可以包含比較運(yùn)算符:= 、 !=、> 、
1 帶IN關(guān)鍵字的子查詢(xún)
子查詢(xún)的思路
select * from emp where dep_id in
(select id from dep where name="技術(shù)" or name="銷(xiāo)售");
鏈表的思路
select * from emp inner join dep
on emp.dep_id = dep.id
where dep.name in ("技術(shù)","銷(xiāo)售");
not in 無(wú)法處理null的值,即子查詢(xún)中如果存在null的值,not in將無(wú)法處理
插入一條dep_id為空的記錄
mysql> insert into emp values(7,'lili','female',48,null);
Query OK, 1 row affected (0.03 sec)
mysql> select * from emp
-> ;
+----+------------+--------+------+--------+
| id | name | sex | age | dep_id |
+----+------------+--------+------+--------+
| 1 | egon | male | 18 | 200 |
| 2 | alex | female | 48 | 201 |
| 3 | wupeiqi | male | 38 | 201 |
| 4 | yuanhao | female | 28 | 202 |
| 5 | liwenzhou | male | 18 | 200 |
| 6 | jingliyang | female | 18 | 204 |
| 7 | lili | female | 48 | NULL |
+----+------------+--------+------+--------+
7 rows in set (0.00 sec)
查詢(xún)出有員工的部門(mén),
select * from dep where id in
(select distinct dep_id from emp);
查詢(xún)出沒(méi)有員工的部門(mén),
select * from dep where id not in
(select distinct dep_id from emp);
解決方案如下
select * from dep where id not in
(select distinct dep_id from emp where dep_id is not null);
2、帶any關(guān)鍵字的子查詢(xún)
在SQL中 any 和some 是同義詞,用法和功能和any一樣
any后也跟子查詢(xún)語(yǔ)句,與in不一樣的地方在哪里
in (子查詢(xún)語(yǔ)句)
in (值1,值2,值3)
而any只能跟子查詢(xún)語(yǔ)句
any必須跟比較運(yùn)算符配合使用
ANY 必須和其他的比較運(yùn)算符共同使用,而且ANY必須將比較運(yùn)算符放在 ANY 關(guān)鍵字之前,
所比較的值需要匹配子查詢(xún)中的任意一個(gè)值,這也就是 ANY 在英文中所表示的意義
select * from emp where dep_id in
(select id from dep where name in ("技術(shù)","人力資源"));
select * from emp where dep_id = any
(select id from dep where name in ("技術(shù)","人力資源"));
select * from emp where dep_id not in
(select id from dep where name in ("技術(shù)","人力資源"));
select * from emp where ! (dep_id = any(select id from dep where name in ("技術(shù)","人力資源")));
使用 IN 和使用 ANY運(yùn)算符得到的結(jié)果是一致的
也就是說(shuō)“=ANY”等價(jià)于 IN 運(yùn)算符,而“<>ANY”則等價(jià)于 NOT IN 運(yùn)算符
3 帶ALL關(guān)鍵字的子查詢(xún)
all同any類(lèi)似,只不過(guò)all表示的是所有,any表示任一
查詢(xún)出那些薪資比所有部門(mén)的平均薪資都高的員工=》薪資在所有部門(mén)平均線以上的狗幣資本家
select * from employee where salary > all
(select avg(salary) from employee where depart_id is not null group by depart_id);
查詢(xún)出那些薪資比所有部門(mén)的平均薪資都低的員工=》薪資在所有部門(mén)平均線以下的無(wú)產(chǎn)階級(jí)勞苦大眾
select * from employee where salary < all
(select avg(salary) from employee where depart_id is not null group by depart_id);
查詢(xún)出那些薪資比任意一個(gè)部門(mén)的平均薪資高的員工=》薪資在任一部門(mén)平均線以上的員工
select * from employee where salary > any
(select avg(salary) from employee where depart_id is not null group by depart_id);
查詢(xún)出那些薪資比任意一個(gè)部門(mén)的平均薪資低的員工=》薪資在任一部門(mén)平均線以下的員工
select * from employee where salary < any
(select avg(salary) from employee where depart_id is not null group by depart_id);
4 帶比較運(yùn)算符的子查詢(xún)
比較運(yùn)算符:=、!=、>、>=、
查詢(xún)大于所有人平均年齡的員工名與年齡
mysql> select name,age from emp where age > (select avg(age) from emp);
+---------+------+
| name | age |
+---------+------+
| alex | 48 |
| wupeiqi | 38 |
+---------+------+
2 rows in set (0.00 sec)
查詢(xún)大于部門(mén)內(nèi)平均年齡的員工名、年齡
select t1.name,t1.age from emp t1
inner join
(select dep_id,avg(age) avg_age from emp group by dep_id) t2
on t1.dep_id = t2.dep_id
where t1.age > t2.avg_age;
5 帶EXISTS關(guān)鍵字的子查詢(xún)
EXISTS關(guān)字鍵字表示存在。在使用EXISTS關(guān)鍵字時(shí),內(nèi)層查詢(xún)語(yǔ)句不返回查詢(xún)的記錄。
而是返回一個(gè)真假值。True或False
當(dāng)返回True時(shí),外層查詢(xún)語(yǔ)句將進(jìn)行查詢(xún);當(dāng)返回值為False時(shí),外層查詢(xún)語(yǔ)句不進(jìn)行查詢(xún)
語(yǔ)法
select * from 表1 where exists (select * from 表2);
5.1 in與exists
!!!!!!當(dāng)in和exists在查詢(xún)效率上比較時(shí),in查詢(xún)的效率快于exists的查詢(xún)效率!!!!!!
exists
exists后面一般都是子查詢(xún),后面的子查詢(xún)被稱(chēng)做相關(guān)子查詢(xún)(即與主語(yǔ)句相關(guān)),當(dāng)子查詢(xún)返回行數(shù)時(shí),exists條件返回true,
否則返回false,exists是不返回列表的值的,exists只在乎括號(hào)里的數(shù)據(jù)能不能查找出來(lái),是否存在這樣的記錄。
例
查詢(xún)出那些班級(jí)里有學(xué)生的班級(jí)
select * from class where exists (select * from stu where stu.cid=class.id)
exists的執(zhí)行原理為:
1、依次執(zhí)行外部查詢(xún):即select * from class
2、然后為外部查詢(xún)返回的每一行分別執(zhí)行一次子查詢(xún):即(select * from stu where stu.cid=class.cid)
3、子查詢(xún)?nèi)绻祷匦?#xff0c;則exists條件成立,條件成立則輸出外部查詢(xún)?nèi)〕龅哪菞l記錄
in
in后跟的都是子查詢(xún),in()后面的子查詢(xún) 是返回結(jié)果集的
例
查詢(xún)和所有女生年齡相同的男生
select * from stu where sex='男' and age in(select age from stu where sex='女')
in的執(zhí)行原理為:
in()的執(zhí)行次序和exists()不一樣,in()的子查詢(xún)會(huì)先產(chǎn)生結(jié)果集,
然后主查詢(xún)?cè)偃ソY(jié)果集里去找符合要求的字段列表去.符合要求的輸出,反之則不輸出.
例如:查詢(xún)有員工的部門(mén)=》
select * from dep where exists (select * from emp where dep.id=emp.dep_id);
5.2 not in與 not exists
not exists的效果 高于 not in
not in()子查詢(xún)的執(zhí)行順序是:
為了證明not in成立,即找不到,需要一條一條地查詢(xún)表,符合要求才返回子查詢(xún)的結(jié)果集,
不符合的就繼續(xù)查詢(xún)下一條記錄,直到把表中的記錄查詢(xún)完,只能查詢(xún)?nèi)坑涗洸拍茏C明,并沒(méi)有用到索引
not exists:對(duì)結(jié)果取反,沒(méi)有返回值才為真
就是對(duì)exists完全取反,下面的循環(huán)語(yǔ)句中全部滿足才為真,有一個(gè)不滿足就是假
select * from dep where not exists (select * from emp where 203=emp.dep_id);
例:查詢(xún)選修了所有課程的學(xué)生id、name:
實(shí)現(xiàn)方式一:選修了三門(mén)課程的學(xué)生就是選修了所有課程的學(xué)生
select s.id,s.name from student as s inner join student2course as sc
on s.id = sc.sid
group by sc.sid
having count(sc.cid) = (select count(id) from course);
實(shí)現(xiàn)方式二:找到這樣的學(xué)生,該學(xué)生不存在沒(méi)有選修過(guò)的課程
select * from student as s where not exists (
select * from course as c not exists (
select * from student2course as sc where sc.sid = s.id and sc.cid = c.id
)
);
select * from student as s where not exists (
select * from course as c where not exists (
select * from student2course as sc where sc.sid = s.id and sc.cid = c.id
)
);
學(xué)生記錄可以過(guò)濾出來(lái),一定是子查詢(xún)內(nèi)沒(méi)有記錄
for 學(xué)生: # s.id=2
for 課程: # c.id=1
for 學(xué)生2課程: # sc.sid = 2 and sc.cid = 1
pass
==================================
for sid in [1,2,3,4]:
for cid in [1,2,3]:
(sid,cid)
最外層循環(huán)一次
# (1,1)
# (1,2)
# (1,3)
最外層循環(huán)二次
# (2,1)
# (2,2)
# (2,3)
最外層循環(huán)三次
# (3,1)
# (3,2)
# (3,3)
最外層循環(huán)四次
# (4,1)
# (4,2)
# (4,3)
===================================
例2、查詢(xún)沒(méi)有選擇所有課程的學(xué)生,即沒(méi)有全選的學(xué)生。=》找出這樣的學(xué)生,存在沒(méi)有選修過(guò)的課程
select * from student as s where exists (
select * from course as c where not exists (
select * from student2course as sc where sc.sid = s.id and sc.cid = c.id
)
);
例3、查詢(xún)一門(mén)課也沒(méi)有選的學(xué)生=》找出這樣的學(xué)生,不存在選修過(guò)的課程
select * from student as s where not exists (
select * from course as c where exists (
select * from student2course as sc where sc.sid = s.id and sc.cid = c.id
)
);
例4、查詢(xún)至少選修了一門(mén)課程的學(xué)生=》找出這樣的學(xué)生,存在選修過(guò)課程
select * from student as s where exists (
select * from course as c where exists (
select * from student2course as sc where sc.sid = s.id and sc.cid = c.id
)
);
總結(jié)
以上是生活随笔為你收集整理的mysql联合子查询_2020-09-08MySQL多表联合查询之子查询的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 2011年五粮液42度价格?
- 下一篇: 计算机网络讨论4,计算机网络实验四