在1个查询中使用案例,计数和分组

时间:2018-04-13 02:10:29

标签: sql sql-server tsql

我需要加入3个表,对数据进行计数/求和,并对数据进行分组。以下是我的表格的简化版本。

    People p
ID 
1
2
3
    Accounts a
ID | Balance | PeopleFK
1  | 50      | 1
2  | 25      | 2
3  | 15      | 3

    Cards c
ID | Status | PeopleFK
1  | Active | 1
2  | Inact  | 1
3  | Active | 2
4  | Other  | 2

到目前为止我所拥有的:

select sum(a.balance),count(c.*),
case when c.status='Active' then 'Active'
case when c.status IN ('Inactive','Other') then 'Inact'
case when c.status is null then 'No Card' end as 'CardStatus'
from people p
join accounts a on p.id=a.PeopleFK
left join cards c on p.id=c.PeopleFK
group by c.status

必需的结果如下:

Balance  |  CardStatus  |  CardCount
50       |  Active      |  2
25       | Inactive     |  1
0        | NoCard       |  1

但我的结果是按所有卡状态分组的。我理解为什么会发生这种情况,但我不确定如何在不为每个案例编写单独的查询的情况下解决这个问题。

因此,他们不是将非活动和其他组合在一起,而是将它们分开。

我还在玩弄这个但有任何建议吗?

2 个答案:

答案 0 :(得分:1)

使用Group By时,SELECT语句可能只包含Group By语句中的字段或聚合函数(如SUM或COUNT)。

您可以使用a Common Table Expression (CTE)将构建CardStatus的逻辑合并到select语句中,然后将其汇集到一个新的查询中,该查询在group by和select语句中利用它

;WITH BalanceCards AS (
    SELECT a.balance,
           (CASE WHEN c.status='Active'                THEN 'Active'
                 WHEN c.status IN ('Inactive','Other') THEN 'Inact'
                 WHEN c.status IS NULL                 THEN 'No Card' 
            END) AS CardStatus
    FROM people p
    JOIN accounts a ON p.id = a.PeopleFK
    LEFT JOIN cards c ON p.id = c.PeopleFK
)
SELECT bs.CardStatus, 
       SUM(bs.balance) As Total, 
       COUNT(*) As [Count]
FROM BalanceCards bs
GROUP BY bs.CardStatus

答案 1 :(得分:1)

我相信这是您想要的查询:

select (case when c.status = 'Active' then 'Active'
             when c.status in ('Inactive','Other') then 'Inact'
             when c.status is null then 'No Card'
        end) as CardStatus,
       count(c.PeopleFK) as CardCount, sum(a.balance) as balance
from people p join
     accounts a
     on p.id = a.PeopleFK left join
     cards c
     on p.id = c.PeopleFK
group by (case when c.status = 'Active' then 'Active'
               when c.status in ('Inactive', 'Other') then 'Inact'
               when c.status is null then 'No Card'
          end);

注意:

  • 您想要一个case表达式来计算状态。
  • 需要在GROUP BY
  • 中重复
  • 不要对列别名使用单引号。仅对字符串和日期常量使用单引号。
  • count(c.*)在SQL Server中无效。