如何正确合并SQL查询?员工订单统计问题求助
1. UNION语句的错误原因
你的UNION用法完全偏离了正确场景:
- UNION的作用是追加行,而非合并列。你第一个查询返回的是每个员工的总订单数(延迟列留空),第二个查询返回的是每个员工的延迟订单数(总订单列留空),合并后每个员工会被拆成两行数据,这就是你看到“数据偏移”的核心原因。
- 列头错误是因为UNION的列名以第一个查询为准,第一个查询的第五列没有指定别名,所以显示为NULL;你看到的结果列头混乱,本质是查询逻辑错误,不该用UNION来合并两个统计维度的结果。
- 另外你的
GROUP BY存在严重问题:仅按LastName分组,但SELECT中包含EmpId和FirstName,如果有重名员工,会被错误合并成一行,统计结果彻底失真。必须按EmpId(主键)分组,或者把所有非聚合列都加入GROUP BY。
2. 更优的实现方案
不需要拆分查询再合并,一次分组聚合就能完成需求,用条件聚合直接在统计函数里嵌入判断逻辑即可:
方案一:包含无订单的员工(总订单数显示为0)
SELECT e.EmpID, e.LastName, e.FirstName, COUNT(o.OrderID) AS TotalCount, SUM(CASE WHEN julianday(o.ShippedDate) - julianday(o.RequiredDate) >= 5 THEN 1 ELSE 0 END) AS LateCount FROM Employees e LEFT JOIN Orders o ON e.EmpID = o.EmpID GROUP BY e.EmpID, e.LastName, e.FirstName;
方案二:仅统计有订单的员工
SELECT e.EmpID, e.LastName, e.FirstName, COUNT(*) AS TotalCount, COUNT(CASE WHEN julianday(o.ShippedDate) - julianday(o.RequiredDate) >= 5 THEN 1 ELSE NULL END) AS LateCount FROM Employees e INNER JOIN Orders o ON e.EmpID = o.EmpID GROUP BY e.EmpID, e.LastName, e.FirstName;
说明:
- 用
CASE WHEN判断延迟条件,SUM会对符合条件的行累加1,否则加0,直接得到延迟订单数;COUNT会自动忽略NULL值,所以符合条件返回1、否则返回NULL的写法也能得到正确统计。 - 分组必须包含
EmpID(主键),确保每个员工单独分组,避免重名导致的统计错误。
内容的提问来源于stack exchange,提问作者BusterTheFatCat
相关产品推荐
相关产品推荐

