不同组的COUNT和COUNT DISTINCT

时间:2016-08-13 02:47:57

标签: sql-server sql-server-2014

对于基于SQL Server的报告,

表:

CID   Date     ID   Service    Days
1   3/7/2016    1   Individual  3
2   4/5/2016    2   Individual  4
3   5/24/2016   1   Individual  3
4   4/4/2016    4   Group       2
5   4/4/2016    4   Group       2
6   2/18/2016   4   Group       2
7   5/5/2016    5   Group       1
8   5/5/2016    5   Group       1

我使用了这段代码:

SELECT 
    ID,
    Service,
    COUNT(WHEN Days = 4 THEN 1 END) AS '4Days',
    COUNT(WHEN Days = 3 THEN 1 END) AS '3Days',
    COUNT(WHEN Days = 2 THEN 1 END) AS '2Days',
    COUNT(WHEN Days = 1 THEN 1 END) AS '1Day'

    FROM Table T1
    GROUP BY
    ID,
    Service

给了我这个输出:

ID  Service      4Days   3Days    2Days  1Day
1   Individual     0       2       0      0
2   Individual     1       0       0      0
4   Group          0       0       3      0
5   Group          0       0       0      2

我想要做的不是将群组服务视为单独个人的单独服务,而是将每个群组作为一项服务。与日期或ID一起使用的Count Distinct可以帮助我做到这一点,但我不知道如何使用个人服务进行游戏,我只想单独计算它们而不使用DISTINCT。所以期望的输出是:

ID  Service      4Days   3Days    2Days  1Day
1   Individual     0       2       0      0
2   Individual     1       0       0      0
4   Group          0       0       2      0
5   Group          0       0       0      1

如果我过度简化问题,我会编辑帖子,因为这是虚拟数据。

3 个答案:

答案 0 :(得分:1)

根据您的上一次编辑,这是我能想到的最直接的处理查询的方式:

with cte as (
  select id, service, days
    from table t1
   where service = 'Individual'
   union all
  select id, service, days
    from table t1
   where service = 'Group'
   group by id, service, days, date
)
select id,
       service,
       count(case when days = 4 then 'X' end) as [4Days],
       count(case when days = 3 then 'X' end) as [3Days],
       count(case when days = 2 then 'X' end) as [2Days],
       count(case when days = 1 then 'X' end) as [1Day]
  from cte
 group by id, service

答案 1 :(得分:1)

如果我对“2Days”列服务类型没有错,如果我们的分组基于“日期”列,则“组”计数应为“2”,如果是,请尝试以下操作:

SELECT 
    ID,
    Service,
    CASE WHEN MAX(t.days) = 4 THEN MAX(t.date) ELSE 0 END AS '4Days',
    CASE WHEN MAX(t.days) = 3 THEN MAX(t.date) ELSE 0 END AS '3Days',
    CASE WHEN MAX(t.days) = 2 THEN MAX(t.date) ELSE 0 END AS '2Days',
    CASE WHEN MAX(t.days) = 1 THEN MAX(t.date) ELSE 0 END AS '1Day'
FROM table T1
OUTER APPLY (SELECT days, 
                 COUNT(DISTINCT(date)) date 
             FROM Table WHERE days = t1.days GROUP BY days) t
GROUP BY id, service
ORDER BY ID

答案 2 :(得分:1)

如果您愿意,可以这样使用distinct

count(distinct
    case when Days = 1 then case when Service = 'Group' then 1 else "Date" end end
) as [1Day]

根据您的索引,在查询中引入另一列可能会更改查询计划。我怀疑可能不是这种情况。