[英]SQL: count rows where column = a value AND another column is the same as values in the group where the first condition is true?
I need to count the number of rows for each employee where the status = 9
and the date
is the same as other rows within that employee_id
where the status = 9
.我需要计算每个员工的行数,其中
status = 9
并且date
与该employee_id
中status = 9
其他行相同。 I also want the employee_id
and count_all
, a count of all the rows for each employee.我还想要
employee_id
和count_all
,这是每个员工所有行的计数。
Figuring out how to get the count_same_date_status_9
column is where I am stuck.弄清楚如何获得
count_same_date_status_9
列是我卡住的地方。 These dates are made up just for the example so I dont want to put them explicitly into the query.这些日期仅用于示例,所以我不想将它们明确地放入查询中。
My table:我的表:
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
I want to return the following:我想返回以下内容:
employee_id count_same_date_status_9 count_all
1 2 3
2 0 3
3 0 2
4 3 3
You can use:您可以使用:
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;
Which, for your sample data:其中,对于您的示例数据:
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;
Outputs:输出:
\nEMPLOYEE_ID |EMPLOYEE_ID | COUNT_9 |
COUNT_9 | COUNT_ALL
COUNT_ALL\n----------: |
----------: | ------: |
------: | --------:
--------:\n 1 |
1 | 2 |
2 | 3
3\n 2 |
2 | 0 |
0 | 3
3\n 3 |
3 | 0 |
0 | 2
2\n 4 |
4 | 3 |
3 | 3
3\n
The logic you want is a bit counter-intuitive, but I think you can do this with two levels of aggregation:您想要的逻辑有点违反直觉,但我认为您可以通过两个级别的聚合来做到这一点:
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
Demo on DB Fiddle : DB Fiddle 上的演示:
EMPLOYEE_ID | COUNT_SAME_DATE_STATUS_9 | COUNT_ALL ----------: | -----------------------: | --------: 1 | 2 | 3 2 | 0 | 3 3 | 0 | 2 4 | 3 | 3
The result can be achieved with a simple group by, then a subquery to find the most status = 9
that occured on the same day.结果可以通过一个简单的 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
this might work for MSSQL;这可能适用于 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
Someone gave this answer then deleted it so I'm not sure who to give credit to, but this query seems to be working as intended and is pretty simple to read:有人给出了这个答案,然后删除了它,所以我不确定该归功于谁,但是这个查询似乎按预期工作,并且很容易阅读:
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.