繁体   English   中英

SQL:计算行数,其中列 = 一个值且另一列与第一个条件为真的组中的值相同?

[英]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_idstatus = 9其他行相同。 我还想要employee_idcount_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

DB Fiddle 上的演示

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM