SELECT基于列值的计数

时间:2019-10-23 15:08:13

标签: sql database tsql sql-server-2008

我有一张这样的桌子

Date  | Name  | StateData |
------+-------+-----------+    
xxxxx | Tom   | OPENED    |
xxxxx | David | NULL      |
xxxxx | Tom   | NULL      |
xxxxx | Brand | CLOSED    |
xxxxx | Brand | NULL      |
xxxxx | Brand | OPENED    |

我想要实现的结果是这样的

Date | Name | OPENED | CLOSED | UNUSED |
-----+------+--------+--------+--------+
xxxxx| Tom  |   1    |    0   |    1   |
xxxxx| David|   0    |    0   |    1   |
xxxxx| Brand|   1    |    1   |    1   |

我已经尝试过类似的事情

SELECT 
    Name,
    [OPENED] = COUNT(CASE WHEN StateData ='OPENED' THEN StateData END),
    [CLOSED] = COUNT(CASE WHEN StateData ='CLOSED' THEN StateData END),
    [UNUSED] = COUNT(CASE WHEN StateData IS NULL THEN StateData END)
FROM 
    [dbo].[StateData]
GROUP BY
    Name

结果是,“名称”列中至少没有重复的记录,但是通过简单的select count(*)可以清楚地看到列中的计数不正确。

首先,我在Google上做了一些示例,并在上面进行了选择。

2 个答案:

答案 0 :(得分:3)

我会改用SUM()。您对NULL有疑问:

SELECT Name,
       SUM(CASE WHEN StateData = 'OPENED' THEN 1 ELSE 0 END) as opened
       SUM(CASE WHEN StateData = 'CLOSED' THEN 1 ELSE 0 END) as closed
       SUM(CASE WHEN StateData IS NULL THEN 1 ELSE 0 END) as unused
FROM [dbo].[StateData]
GROUP BY Name;

您的unused始终为零,因为COUNT(NULL)始终为零。

答案 1 :(得分:2)

这是一个“简单”的枢轴。但是,就我个人而言,我更喜欢使用交叉表,而不是限制性的PIVOT运算符:

SELECT [Date],
       [Name],
       COUNT(CASE StateData WHEN 'OPENED' THEN 1 END) AS OPENED,
       COUNT(CASE StateData WHEN 'CLOSED' THEN 1 END) AS CLOSED,
       COUNT(CASE WHEN StateData IS NULL THEN 1 END) AS UNUSED
FROM YourTable
GROUP BY [Date],
         [Name];

请注意,您标记的SQL Server版本(2008)现在完全不受支持。因此,强烈建议您尽快查看升级路径。