4

使用 CASE 语句将计数选择到多列时遇到问题。CASE 语句对我的工作方式就像 C/C++ 中的 IF 语句。如果值等于 X,则执行 Y 否则执行 Z。

为了帮助解释这个问题,让我提供一个查询,它计算名为“Names”的列中的名称,并按“Date”列对它们进行分组。

SELECT [Date]
       COUNT( CASE WHEN [Name] = 'John' THEN 1 ELSE NULL END) AS 'John',
       COUNT( CASE WHEN [Name] = 'Joe' THEN 1 ELSE NULL END) AS 'Joe',
       COUNT( CASE WHEN [Name] = 'Moe' THEN 1 ELSE NULL END) AS 'Moe',
       COUNT( CASE WHEN [Name] = 'Nick' THEN 1 ELSE NULL END) AS 'Nick',
       COUNT( CASE WHEN [Name] = 'Zack' THEN 1 ELSE NULL END) AS 'Zack'
FROM [MyDatabase].[dbo].[LogInData]
WHERE [Date] >= '2013-07-01'
GROUP BY [Date]

这假设我知道我想计算的名字。如果我想在单行中计算查询中未定义的新名称怎么办?我怎样才能动态地搜索表中的所有 DISTINCT 名称,并像上面那样自动对它们进行计数,而无需向代码中添加新名称?

感谢您的任何帮助,您可以提供。我仍在尝试学习使用 SQL 编写复杂查询的不同方法。我不是在寻找一个确切的答案,但是任何能帮助我指出正确方向的帮助都会很棒。我完全是为了学习和扩展我的知识,而不是给我的东西。

4

2 回答 2

9

你会这样做:

SELECT [Date], [Name], COUNT(*)
  FROM ...
  GROUP BY [Date], [Name];

那么也许你可以旋转,但你不一定要在查询中这样做。在不知道您拥有的名称(以及列数)的情况下这样做将需要动态 SQL 来构建适当的数据透视 - 但同样,您可以在表示层转置此信息并让 SQL Server 以优化的方式返回此数据去做。

DECLARE @date date = '20130701';

DECLARE @sql  nvarchar(max) = N'', 
        @cols nvarchar(max) = N'';

SELECT @cols = STUFF((SELECT N',' + QUOTENAME(Name)
               FROM dbo.LoginData
               WHERE [Date] >= @date
               GROUP BY Name
               FOR XML PATH(''),
               TYPE).value(N'./text()[1]', N'nvarchar(max)'), 1, 1, '');

SET @sql = N'SELECT *
  FROM (SELECT * FROM dbo.LoginData AS d
  WHERE [Date] >= @date
  ) AS d
  PIVOT (COUNT([Name]) FOR [Name] IN (' + @cols + ')) AS p;';

EXEC sys.sp_executesql @sql, N'@date date', @date;
于 2013-07-25T17:33:07.590 回答
0

如果您不需要将它们全部放在一行中,那么您可以这样做:

SELECT [Date],
       [Name],
       COUNT(*)
FROM [MyDatabase].[dbo].[LogInData]
WHERE [Date] >= '2013-07-01'
GROUP BY [Date],[Name]
于 2013-07-25T17:33:50.973 回答