mysql联合子查询_2020-09-08MySQL多表联合查询之子查询
一、子查詢 in
1:子查詢是將一個查詢語句嵌套在另一個查詢語句中。
2:內層查詢語句的查詢結果,可以為外層查詢語句提供查詢條件。
3:子查詢中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等關鍵字
4:還可以包含比較運算符:= 、 !=、> 、
1 帶IN關鍵字的子查詢
子查詢的思路
select * from emp where dep_id in
(select id from dep where name="技術" or name="銷售");
鏈表的思路
select * from emp inner join dep
on emp.dep_id = dep.id
where dep.name in ("技術","銷售");
not in 無法處理null的值,即子查詢中如果存在null的值,not in將無法處理
插入一條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)
查詢出有員工的部門,
select * from dep where id in
(select distinct dep_id from emp);
查詢出沒有員工的部門,
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關鍵字的子查詢
在SQL中 any 和some 是同義詞,用法和功能和any一樣
any后也跟子查詢語句,與in不一樣的地方在哪里
in (子查詢語句)
in (值1,值2,值3)
而any只能跟子查詢語句
any必須跟比較運算符配合使用
ANY 必須和其他的比較運算符共同使用,而且ANY必須將比較運算符放在 ANY 關鍵字之前,
所比較的值需要匹配子查詢中的任意一個值,這也就是 ANY 在英文中所表示的意義
select * from emp where dep_id in
(select id from dep where name in ("技術","人力資源"));
select * from emp where dep_id = any
(select id from dep where name in ("技術","人力資源"));
select * from emp where dep_id not in
(select id from dep where name in ("技術","人力資源"));
select * from emp where ! (dep_id = any(select id from dep where name in ("技術","人力資源")));
使用 IN 和使用 ANY運算符得到的結果是一致的
也就是說“=ANY”等價于 IN 運算符,而“<>ANY”則等價于 NOT IN 運算符
3 帶ALL關鍵字的子查詢
all同any類似,只不過all表示的是所有,any表示任一
查詢出那些薪資比所有部門的平均薪資都高的員工=》薪資在所有部門平均線以上的狗幣資本家
select * from employee where salary > all
(select avg(salary) from employee where depart_id is not null group by depart_id);
查詢出那些薪資比所有部門的平均薪資都低的員工=》薪資在所有部門平均線以下的無產階級勞苦大眾
select * from employee where salary < all
(select avg(salary) from employee where depart_id is not null group by depart_id);
查詢出那些薪資比任意一個部門的平均薪資高的員工=》薪資在任一部門平均線以上的員工
select * from employee where salary > any
(select avg(salary) from employee where depart_id is not null group by depart_id);
查詢出那些薪資比任意一個部門的平均薪資低的員工=》薪資在任一部門平均線以下的員工
select * from employee where salary < any
(select avg(salary) from employee where depart_id is not null group by depart_id);
4 帶比較運算符的子查詢
比較運算符:=、!=、>、>=、
查詢大于所有人平均年齡的員工名與年齡
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)
查詢大于部門內平均年齡的員工名、年齡
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關鍵字的子查詢
EXISTS關字鍵字表示存在。在使用EXISTS關鍵字時,內層查詢語句不返回查詢的記錄。
而是返回一個真假值。True或False
當返回True時,外層查詢語句將進行查詢;當返回值為False時,外層查詢語句不進行查詢
語法
select * from 表1 where exists (select * from 表2);
5.1 in與exists
!!!!!!當in和exists在查詢效率上比較時,in查詢的效率快于exists的查詢效率!!!!!!
exists
exists后面一般都是子查詢,后面的子查詢被稱做相關子查詢(即與主語句相關),當子查詢返回行數時,exists條件返回true,
否則返回false,exists是不返回列表的值的,exists只在乎括號里的數據能不能查找出來,是否存在這樣的記錄。
例
查詢出那些班級里有學生的班級
select * from class where exists (select * from stu where stu.cid=class.id)
exists的執行原理為:
1、依次執行外部查詢:即select * from class
2、然后為外部查詢返回的每一行分別執行一次子查詢:即(select * from stu where stu.cid=class.cid)
3、子查詢如果返回行,則exists條件成立,條件成立則輸出外部查詢取出的那條記錄
in
in后跟的都是子查詢,in()后面的子查詢 是返回結果集的
例
查詢和所有女生年齡相同的男生
select * from stu where sex='男' and age in(select age from stu where sex='女')
in的執行原理為:
in()的執行次序和exists()不一樣,in()的子查詢會先產生結果集,
然后主查詢再去結果集里去找符合要求的字段列表去.符合要求的輸出,反之則不輸出.
例如:查詢有員工的部門=》
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()子查詢的執行順序是:
為了證明not in成立,即找不到,需要一條一條地查詢表,符合要求才返回子查詢的結果集,
不符合的就繼續查詢下一條記錄,直到把表中的記錄查詢完,只能查詢全部記錄才能證明,并沒有用到索引
not exists:對結果取反,沒有返回值才為真
就是對exists完全取反,下面的循環語句中全部滿足才為真,有一個不滿足就是假
select * from dep where not exists (select * from emp where 203=emp.dep_id);
例:查詢選修了所有課程的學生id、name:
實現方式一:選修了三門課程的學生就是選修了所有課程的學生
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);
實現方式二:找到這樣的學生,該學生不存在沒有選修過的課程
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
)
);
學生記錄可以過濾出來,一定是子查詢內沒有記錄
for 學生: # s.id=2
for 課程: # c.id=1
for 學生2課程: # sc.sid = 2 and sc.cid = 1
pass
==================================
for sid in [1,2,3,4]:
for cid in [1,2,3]:
(sid,cid)
最外層循環一次
# (1,1)
# (1,2)
# (1,3)
最外層循環二次
# (2,1)
# (2,2)
# (2,3)
最外層循環三次
# (3,1)
# (3,2)
# (3,3)
最外層循環四次
# (4,1)
# (4,2)
# (4,3)
===================================
例2、查詢沒有選擇所有課程的學生,即沒有全選的學生。=》找出這樣的學生,存在沒有選修過的課程
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、查詢一門課也沒有選的學生=》找出這樣的學生,不存在選修過的課程
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、查詢至少選修了一門課程的學生=》找出這樣的學生,存在選修過課程
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
)
);
總結
以上是生活随笔為你收集整理的mysql联合子查询_2020-09-08MySQL多表联合查询之子查询的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2011年五粮液42度价格?
- 下一篇: centos odbc mysql_Ce