基于public.event_by_wkr表的工时统计SQL查询需求
我来帮你搞定这两个工时统计需求,先把你的源表数据整理成清晰的Markdown表格,方便咱们查看:
| F Name | L Name | Event ID | Group ID | Hours | Event Type | Event Name |
|---|---|---|---|---|---|---|
| Bill | Johnson | 1 | 3 | Event | Indirect | |
| Janet | Jackson | 1 | 1 | Group | ||
| Bill | Johnson | 1 | 1 | Group | ||
| Chris | Margot | 2 | 1.5 | Event | Direct | |
| Janet | Jackson | 1 | 1 | Group |
接下来针对你提出的两个统计目标,用自连接+聚合函数来实现,完全贴合你的需求:
需求1:统计Event Type不为Group且不为Direct的Hours总和
这个需求比较直接,用WHERE条件过滤掉不需要的类型后求和就行:
SELECT SUM(hours) AS non_group_non_direct_total_hours FROM public.event_by_wkr WHERE event_type NOT IN ('Group', 'Direct');
对照你的数据,这个查询会返回3,也就是Bill那条Indirect类型的工时总和。
需求2:统计Event Type为Group的工时,每人每个Group ID仅统计一次
这里的核心是对同一用户(F Name+L Name)+同一Group ID的重复记录去重,只保留一条的工时。按照你要求的自连接方式,我们可以用数据库内置的行标识符(比如PostgreSQL的ctid)来区分同组同用户的不同行,然后只统计每组每个用户的第一条记录:
SELECT SUM(e.hours) AS unique_group_total_hours FROM public.event_by_wkr e LEFT JOIN public.event_by_wkr e2 ON e.f_name = e2.f_name AND e.l_name = e2.l_name AND e.group_id = e2.group_id AND e.ctid < e2.ctid -- 标记出同一组同一用户的后续重复行 WHERE e.event_type = 'Group' AND e2.ctid IS NULL; -- 只保留每组每个用户的第一条记录
如果你的数据库不是PostgreSQL,也可以把ctid换成对应的行唯一标识(比如MySQL的ROWID)。根据你的数据,Janet的两条Group记录只会被统计1小时,加上Bill的1小时,最终总和是2。
可选:一次性获取两个统计结果
如果想在一个查询里拿到两个统计值,可以用子查询把两个结果合并:
SELECT (SELECT SUM(hours) FROM public.event_by_wkr WHERE event_type NOT IN ('Group', 'Direct')) AS non_group_non_direct_total, (SELECT SUM(e.hours) FROM public.event_by_wkr e LEFT JOIN public.event_by_wkr e2 ON e.f_name = e2.f_name AND e.l_name = e2.l_name AND e.group_id = e2.group_id AND e.ctid < e2.ctid WHERE e.event_type = 'Group' AND e2.ctid IS NULL) AS unique_group_total;
内容的提问来源于stack exchange,提问作者user45481
相关产品推荐
相关产品推荐

