[英]SQL: count rows where column = a value AND another column is the same as values in the group where the first condition is true?
我需要计算每个员工的行数,其中status = 9
并且date
与该employee_id
中status = 9
其他行相同。 我还想要employee_id
和count_all
,这是每个员工所有行的计数。
弄清楚如何获得count_same_date_status_9
列是我卡住的地方。 这些日期仅用于示例,所以我不想将它们明确地放入查询中。
我的表:
employee_id status date
1 9 10/19/2020
1 7 07/16/2001
1 9 10/19/2020
2 5 08/11/2011
2 9 12/25/2012
2 9 11/19/2013
3 5 06/05/2016
3 4 01/01/2021
4 9 02/15/2018
4 9 02/15/2018
4 9 02/15/2018
我想返回以下内容:
employee_id count_same_date_status_9 count_all
1 2 3
2 0 3
3 0 2
4 3 3
您可以使用:
SELECT employee_id,
MAX( CASE WHEN status = 9 AND cnt > 1 THEN cnt ELSE 0 END ) AS count_9,
SUM( cnt ) AS count_all
FROM (
SELECT employee_id,
status,
dt,
COUNT(*) AS cnt
FROM table_name
GROUP BY employee_id, status, dt
)
GROUP BY employee_id
ORDER BY employee_id;
其中,对于您的示例数据:
CREATE TABLE table_name ( employee_id, status, dt ) AS
SELECT 1, 9, DATE '2020-10-19' FROM DUAL UNION ALL
SELECT 1, 7, DATE '2001-07-16' FROM DUAL UNION ALL
SELECT 1, 9, DATE '2020-10-19' FROM DUAL UNION ALL
SELECT 2, 5, DATE '2011-08-11' FROM DUAL UNION ALL
SELECT 2, 9, DATE '2012-12-25' FROM DUAL UNION ALL
SELECT 2, 9, DATE '2013-11-19' FROM DUAL UNION ALL
SELECT 3, 5, DATE '2016-06-05' FROM DUAL UNION ALL
SELECT 3, 4, DATE '2021-01-01' FROM DUAL UNION ALL
SELECT 4, 9, DATE '2018-02-15' FROM DUAL UNION ALL
SELECT 4, 9, DATE '2018-02-15' FROM DUAL UNION ALL
SELECT 4, 9, DATE '2018-02-15' FROM DUAL;
输出:
\n EMPLOYEE_ID | COUNT_9 | COUNT_ALL\n ----------: | ------: | --------:\n 1 | 2 | 3\n 2 | 0 | 3\n 3 | 0 | 2\n 4 | 3 | 3\n
db<> 在这里摆弄
您想要的逻辑有点违反直觉,但我认为您可以通过两个级别的聚合来做到这一点:
select employee_id,
case when max(cnt2) = 1 then 0 else max(cnt2) end count_same_date_status_9,
sum(cnt1) count_all
from (
select employee_id, dt, count(*) cnt1, sum(case when status = 9 then 1 else 0 end) cnt2
from mytable t
group by employee_id, dt
) t
group by employee_id
order by employee_id
EMPLOYEE_ID | COUNT_SAME_DATE_STATUS_9 | COUNT_ALL ----------: | -----------------------: | --------: 1 | 2 | 3 2 | 0 | 3 3 | 0 | 2 4 | 3 | 3
结果可以通过一个简单的 group by 来实现,然后是一个子查询来查找同一天发生的最多status = 9
。
WITH
employees (employee_id, status, status_date)
AS
(SELECT 1, 9, TO_DATE ('10/19/2020', 'MM/DD/YYYY') FROM DUAL
UNION ALL
SELECT 1, 7, TO_DATE ('07/16/2001', 'MM/DD/YYYY') FROM DUAL
UNION ALL
SELECT 1, 9, TO_DATE ('10/19/2020', 'MM/DD/YYYY') FROM DUAL
UNION ALL
SELECT 2, 5, TO_DATE ('08/11/2011', 'MM/DD/YYYY') FROM DUAL
UNION ALL
SELECT 2, 9, TO_DATE ('12/25/2012', 'MM/DD/YYYY') FROM DUAL
UNION ALL
SELECT 2, 9, TO_DATE ('11/19/2013', 'MM/DD/YYYY') FROM DUAL
UNION ALL
SELECT 3, 5, TO_DATE ('06/05/2016', 'MM/DD/YYYY') FROM DUAL
UNION ALL
SELECT 3, 4, TO_DATE ('01/01/2021', 'MM/DD/YYYY') FROM DUAL
UNION ALL
SELECT 4, 9, TO_DATE ('02/15/2018', 'MM/DD/YYYY') FROM DUAL
UNION ALL
SELECT 4, 9, TO_DATE ('02/15/2018', 'MM/DD/YYYY') FROM DUAL
UNION ALL
SELECT 4, 9, TO_DATE ('02/15/2018', 'MM/DD/YYYY') FROM DUAL)
SELECT employee_id,
NVL ((SELECT MAX (count_9)
FROM ( SELECT employee_id, status_date, COUNT (*) AS count_9
FROM employees e2
WHERE e2.status = 9 AND e2.employee_id = o.employee_id
GROUP BY employee_id, status_date)
HAVING MAX (count_9) > 1),
0) AS count_same_date_status_9,
count_all
FROM ( SELECT employee_id, COUNT (*) AS count_all
FROM employees e1
GROUP BY employee_id) o
ORDER BY employee_id
EMPLOYEE_ID COUNT_SAME_DATE_STATUS_9 COUNT_ALL
______________ ___________________________ ____________
1 2 3
2 0 3
3 0 2
4 3 3
这可能适用于 MSSQL;
select employee_id,sum(A),sum(B) from(
select employee_id,count(*) A ,0 B from TABLENAME group by employee_id,status
union all
select employee_id,0 A,count(*) B from TABLENAME group by employee_id,date
) C group by employee_id
有人给出了这个答案,然后删除了它,所以我不确定该归功于谁,但是这个查询似乎按预期工作,并且很容易阅读:
select employee_id, sum(case when status = 9 then 1 else 0 end) as count_same_date_status_9, count(*) as count_all
from table_name
group by employee_id;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.