简体   繁体   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?

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_idstatus = 9其他行相同。 I also want the employee_id and count_all , a count of all the rows for each employee.我还想要employee_idcount_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

db<>fiddle here db<> 在这里摆弄

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

Query询问

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

Result结果

   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.

相关问题 SQL对列等于特定值的组中的行进行计数 - SQL to count rows in a group where a column is equal to a particular value 如何使用SQL对一列的值&lt;= x和另一列&gt; x的值的行数进行分组和计数? - How can I use SQL to group and count the number of rows where the value for one column is <= x and the value for another column > x? SQL行共享相同的列值,并且在哪里 - SQL rows sharing same column value and with where SQL:返回条件为真的行组 - SQL: return group of rows where condition is true T-SQL 如何选择一列值的计数,而另一列的值相同 - T-SQL How to select count of one column's values where another column's values are the same MySQL-选择列值仅为0的行,按另一列分组? - MySQL - Select rows where column value is only 0, group by another column? SQL - 如何计算不同值(付款)的数量,在它们具有共同的另一个列值(到期日)的行总和之后 - SQL - How to count number of distinct values (payments), after sum of rows where they have another column value (Due Date) in common 如何使用SQL Server中的where条件从table2.rows更新到table1.column值 - How do update to table1.column value from table2.rows count with where condition in SQL server 编写一个SQL查询,以检索列中具有相同值的所有不同行,其中这些行的计数大于1 - Write a SQL query that retrieves all distinct rows having the same value in a column where count of these rows is larger than 1 SQL-计算一列与另一列匹配的行(对) - SQL - count rows where one column matches another (pairs)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM