请问这个SQL的select后的子查询的实现原理是什么?可以用C或python的伪代码解释吗?

 有两个表,一个employees一个departments。现在是要查询每个部门内的员工数量。

SELECT d.*,(
	SELECT COUNT(*)
	FROM `employees` e
	WHERE e.`department_id`=d.`department_id`
) 个数
FROM `departments` d;

查询结果:

问题关键是如果直接执行子查询:

SELECT COUNT(*)
FROM `employees` e,`departments` d
WHERE e.`department_id`=d.`department_id`;

输出结果是所有有对应部门的员工数,输出106,为什么同样的查询放到主查询中就不是106了呢?

关键是子查询与外查询的部门ID关联,相当于分组统计。


-- 单独查询部门表信息
select d.* from `departments` d;

-- 单独查询部门表信息,并追加一个标量查询作为字段
SELECT d.*,(
    -- 针对每一行,单独运行一次,并返回标量值
	SELECT COUNT(*)
    -- 从员工表中查询,返回符合条件的汇总数
	FROM `employees` e
    -- 条件为当前员工部门与执行本次查询时,部门表的id一致
	WHERE e.`department_id`=d.`department_id`
) 个数
FROM `departments` d;

-- 换个写法,可以支持表值结果
select *
from `departments` d
cross apply
(
    select count(0) as 人数
        ,sum(case when 性别='男' then 1 else 0 end) as 男性人数
    from `employees` e
    where e.`department_id`=d.`department_id`
) a;

-- 再换个写法
SELECT d.`department_name`,COUNT(*) as 人数
FROM `employees` e,`departments` d
WHERE e.`department_id`=d.`department_id`
group by d.`department_id`,d.`department_name`;

-- 再再换个写法
select d.`department_name`,COUNT(*) as 人数 
from `departments` d
left join `employees` e on e.`department_id`=d.`department_id`
group by d.`department_id`,d.`department_name`;

-- 最后换个写法
select a.*,e.人数
from `departments` d
left join (
    select `department_id`,count(0) as 人数
    FROM `employees`
    group by `department_id`
    
) e on e.`department_id`=d.`department_id`


-- 最后回答你这个指令
-- 你这个指令的确是统计了所有可以找到部门的员工的数量
-- 可是你这个指令并没有按部门分组,也就是说,前边那些指令按部门得到的人数的总和
-- 等于你这个指令得到的结果
-- 
SELECT COUNT(*)
FROM `employees` e,`departments` d
WHERE e.`department_id`=d.`department_id`;

 

第一条语句和第二条语句不一样,第一条是把子查询当做列查询,第二条是一个内查询或者叫多表查询,数据相同情况下,结果会不一样

您好,我是有问必答小助手,您的问题已经有小伙伴解答了,您看下是否解决,可以追评进行沟通哦~

如果有您比较满意的答案 / 帮您提供解决思路的答案,可以点击【采纳】按钮,给回答的小伙伴一些鼓励哦~~

ps:问答VIP仅需29元,即可享受5次/月 有问必答服务,了解详情>>>https://vip.csdn.net/askvip?utm_source=1146287632