列子查询 概念
之前上一节我们分类后就知道 所谓列子查询 就是针对 子查询结果为 一列多行的情况
换言之 一个属性(栏目),比如阮菜鸡的奖金, 与多个实例的属性,(多个人的奖金),进行比较 ),就是列子查询 也称为多行子查询
那么对于一个值VS一个列表 的比较 我们之前是有涉及的——IN
操作符
就好像python的for in
一样,程序会将值与列表的每个值进行对比(遍历每一个值) 任意一个相等就ok
不记得IN真么使用的可以看之前的章节复习
传送:数据库学习之MySQL (七)——模糊查询 通配符 like ‘between and’ in ‘is null’ 安全等于
ANY ALL
提前说一下 除了IN 操作符 还有别的,分别是ANY 和 ALL
ANY 类似于数学的 存在 ∃
ALL 类似于数学的 任意∀
》如果说 salary > ANY(10,20,30) 意思是 列表(10,20,30)里面,是否存在一个数小于salary的
英语里面就好像一句话:“Is there ANY one smaller than me?” 有比我小的嘛?
》如果说 salary > ALL(10,20,30) 意思是 列表(10,20,30)里面,是否任意一个数,都会小于salary的
英语里面就好像一句话:“Is ALL of you smaller than me?” 都比我小嘛?
列成表格:
代码 | 数学符号 | 中文 | 英文 | 含义 |
---|---|---|---|---|
ANY | ∃ | 存在 | Exist | 有比我小(大)的嘛? |
ALL | ∀ | 任意 | Arbitrary | 都比我小(大)嘛? |
此时 聪明的你已经想到 可以不用ANY ALL的方法:
salary > ANY(10,20,30) 等价于 salary > MIN(10,20,30)
salary > ALL(10,20,30) 等价于 salary > MAX(10,20,30)
不过话说回来 这就是数学的逻辑套路嘛,
比任意一个大 就是比他们最菜的要强就行了
比所有的都大 就是比他们最强的还要强就行了
实例
我们来看实例:
阮菜鸡初来乍到 只认识同期一起面试 一起进公司的人
(hire date
= 阮菜鸡的hiredate)
他们去的部门都不太一样
阮菜鸡想拓展人脉 想认识公司里更多的人
可是 公司的人分布全国各地 location_id 都不一样
如果自己去一个个探索 太麻烦 不如
近水楼台先得月——通过同一批进来的人 认识各个地点的办事处
再去和办事处的公司人员沟通 就容易多了
所以:
—》资源:员工 (同期进来的)的数据库
—》目标:进来员工现在所在部门 以及 部门所在地
—》下一步:去各个所在地 找各个办事处
1️⃣找到同期人+所在部门 通过hiredate筛选
查询方式 子查询 标量:
USE data1;
SELECT
`department_id` AS 部门编号,
CONCAT_WS('-', `last_name`, `first_name`) AS 名字,
`hiredate` AS 入职时间
FROM
employees
WHERE `hiredate` =
(SELECT
`hiredate`
FROM
employees
WHERE `last_name` = '阮')
这些兄弟就是和我一起进公司dio哒:)
化为多行一列 就是:
2️⃣在department表中 根据下面这张对照表
SELECT
`department_name` 办事处名字,
`department_id` 办事处编号,
`location_id` 办事处地点编号
FROM
`departments`
我们可以查到我们已知的办事处 所在地编号 —— 多表查询
这里子列表查询知识的融会贯通:
SELECT
d.`department_name` 办事处名字,
d.`department_id` 办事处编号,
d.`location_id` 办事处地点编号
FROM
`departments` d
WHERE d.`department_id` IN (
SELECT
e.`department_id`
FROM
employees e
WHERE e.`hiredate` =
(
SELECT
`hiredate`
FROM
employees
WHERE `last_name` = '阮')
看着好看点 就是:
SELECT
`department_name` 办事处名字,
`department_id` 办事处编号,
`location_id` 办事处地点编号
FROM `departments`
WHERE `department_id` IN
(SELECT
`department_id`
FROM
employees
WHERE
`hiredate` =
(SELECT
`hiredate`
FROM
`employees`
WHERE `last_name` = '阮'
)
)
ORDER BY 办事处地点编号 ASC
这里有两个问题:
1、 为啥employees.department_id 和department.department_id 不用进行区分
2、为啥直接往d.location_id
办事处地点编号 前面加DISTINCT 不行 有啥解决办法嘛?
第一个问题 你可能这么想:
employees 表和department 表都有属性department_id ,意味着多表查询,需要用表的名字进行区分
而且还有个隐藏的问题 就是之前多表查询中 哪个表为主的问题(可能漏数据)
当然 因为我们是通过查询 和阮菜鸡同一批进来的同志的部门ID结果 再对照department表来解决的
如果department表有 employees里面没有的id, 我们知道了也没用,
如果employees表有 departments没有的id 我们一样没法获取(没地点信息啊)
所以 就是取交集就行了 也就是用内连接
那为啥我们没用多表查询呢?
因为子查询的结果 是没有表数据的属性的 简而言之 他就是一个普普通通的列表
所以直接用就行 这实在是方便 直观 不然得写哭了
我尝试用多表查询的知识解决这个问题 然并暖 还不如子查询来的直观
第二个问题 你有没有想过 1700地点对应三个部门 你要是DISTINCT 地点序号 那三个部门该放哪?
所以简单的解决方式就是 不显示三个部门的id 名字
如下:
SELECT
DISTINCT `location_id` 办事处地点编号
FROM `departments`
WHERE `department_id` IN
(SELECT
`department_id`
FROM
employees
WHERE
`hiredate` =
(SELECT
`hiredate`
FROM
`employees`
WHERE `last_name` = '阮'
)
)
ORDER BY 办事处地点编号 ASC
这样 我们就可以得到地点 然后去拜访各个地点的办事处了2333
值得注意的是 地点代号对应的具体地点呢?
已知还有locations表 如下:
我把这个问题交给你去完成:)
提示:还是子查询
##预告
下一节将讲述 WHERE后面的 行子查询
数据库学习之MySQL (十九)—— WHERE 行子查询
- 本文专栏
MySQL专栏 - 我的其他专栏 希望能够帮到你 ( •̀ ω •́ )✧
- 手把手带你学后端(服务端)
- python这么火 想要深入学习python 玩一下简单的应用嘛?
python应用
- 谢谢大佬支持! 萌新有礼了:)