如何按人员分组计算总工时?SQL嵌套分组查询失败求助
问题分析与解决方案:子查询报错原因及正确工时统计SQL
首先,咱们拆解你遇到的问题,再一步步解决它:
为什么你的子查询无法运行?
你的外层查询报错主要有两个核心原因:
- 子查询必须指定别名:当你把一个查询作为临时表(子查询)在外层使用时,数据库需要知道这个临时结果集的名称,就像给表起个外号一样。你原来的SQL里子查询没有加别名,数据库无法识别它,所以直接报错。
- 内层查询的列缺少明确别名:你内层的
count(Type)和case表达式都没有指定别名,这会导致子查询的列名要么是数据库自动生成的模糊名称(比如count(Type)可能叫count),要么数据库无法解析列的定义,外层查询自然无法正常读取这些列。
另外还要提一句:你原来的内层查询逻辑其实没达到你最终要的「总工时」需求——它是按person和type分组,得到的是每个人每种班次的单独工时,但你需要的是把同一个人的白班、夜班工时加起来的总和,这个逻辑也需要调整。
正确的工时统计SQL写法
写法一:直接计算总工时(最简洁)
不需要嵌套子查询,直接用SUM()结合CASE表达式,把每个班次对应的工时累加,一步到位得到每个人的总工时:
SELECT person, SUM( CASE type WHEN 'day' THEN 8 -- 白班8小时 WHEN 'night' THEN 11 -- 夜班11小时 ELSE 0 -- 休息rest不计入工时 END ) AS hours FROM your_table -- 替换成你的实际表名 WHERE date > '2018-03-30' -- 建议用标准日期格式,避免数据库解析问题 GROUP BY person
写法二:用子查询的正确方式(分步统计场景)
如果一定要用子查询的方式,比如先统计每个人每种班次的数量和对应工时,再在外层求和,那必须给子查询加别名,同时给内层的列指定清晰的别名:
SELECT person, SUM(shift_hours) AS hours FROM ( SELECT person, CASE type WHEN 'day' THEN COUNT(type)*8 WHEN 'night' THEN COUNT(type)*11 ELSE 0 END AS shift_hours FROM your_table WHERE date > '2018-03-30' GROUP BY person, type ) AS shift_details -- 必须给子查询加别名,比如shift_details GROUP BY person
额外提醒
注意日期格式的问题:不同数据库对日期字符串的解析规则不一样,比如MySQL、PostgreSQL更推荐用'YYYY-MM-DD'的标准格式,避免像'3/30/2018'这种格式可能出现的解析错误。
内容的提问来源于stack exchange,提问作者kk luo
相关产品推荐
相关产品推荐

