帮助解决困难的“分组依据”条款

时间:2011-05-22 10:59:40

标签: tsql sql-server-2008

需要一些查询帮助。

我有一张表Managers (ManagerId, ManagerName)

我有一张桌子Statuses (StatusId, StatusName)
(该表中约有10种状态)

我有一张桌子Clients (ClientId, ClientName, ManagerId, StatusId, WhenAdded)
WhenAdded是日期时间类型)

很明显,字段'ManagerId'引用表'Managers'而字段'StatusId'引用表'Statuses'

用户希望在下表中获得有关管理员的一些统计信息(from startDate to endDate using field 'WhenAdded')。

列:

ManagerName, NumberOfClients, NumberOfClientsWithStatus1, NumberOfClientsWithStatus2, NumberOfClientsWithStatus3等等。

名称为NumberOfClientsWithStatusI的列数,其中i是一系列状态,等于表'Statuses'中的行数。

我该怎么做?

t-sql,sql server 2008 r2 express edition。

2 个答案:

答案 0 :(得分:1)

SELECT
    ManagerName,
    COUNT(*) AS NumberOfClients,
    COUNT(CASE WHEN S.StatusId = 1 THEN 1 ELSE NULL END) AS NumberOfClientsWithStatus1,
    COUNT(CASE WHEN S.StatusId = 2 THEN 1 ELSE NULL END) AS NumberOfClientsWithStatus2,
    COUNT(CASE WHEN S.StatusId = 3 THEN 1 ELSE NULL END) AS NumberOfClientsWithStatus3,
    ...
FROM
   Clients C
   JOIN
   Managers M ON C.ManagerId = M.ManagerId
   JOIN
   Statuses S ON C.StatusId = S.StatusId
WHERE
    M.WhenAdded BETWEEN @startDate AND @endDate
GROUP BY
    M.ManagerName

注意:没有干净的方法在SQL(不仅仅是SQL Server)中添加状态列的arbritrary数量,因为它具有固定的列输出。您必须更改状态查询,除非您在客户端

中处理此问题

评论后编辑

SELECT
    ManagerName,
    COUNT(*) AS NumberOfClients,
    COUNT(CASE WHEN S.StatusId = 1 THEN 1 ELSE NULL END) AS NumberOfClientsWithStatus1,
    COUNT(CASE WHEN S.StatusId = 2 THEN 1 ELSE NULL END) AS NumberOfClientsWithStatus2,
    COUNT(CASE WHEN S.StatusId = 3 THEN 1 ELSE NULL END) AS NumberOfClientsWithStatus3,
    ...
FROM
   Managers M ON C.ManagerId = M.ManagerId
   LEFT JOIN
   Clients C
   LEFT JOIN
   Statuses S ON C.StatusId = S.StatusId
WHERE
    M.WhenAdded BETWEEN @startDate AND @endDate
GROUP BY
    M.ManagerName

答案 1 :(得分:0)

如果您知道statuses表将始终包含有限数量的状态,则可以执行以下操作:

SELECT M.ManagerName,
       COUNT(C.ClientId) NumberOfClients,
       SUM(CASE WHEN S.StatusId= 1 THEN 1 ELSE 0 END) NumberOfClientsWithStatus1,
       SUM(CASE WHEN S.StatusId= 2 THEN 1 ELSE 0 END) NumberOfClientsWithStatus2,
       ...
  FROM Clients C
  JOIN Managers M on M.ManagerId = C.ManagerId
  JOIN Statuses S on S.StatusId = C.StatusId
 WHERE C.WhenAdded BETWEEN startDate AND endDate 
 GROUP BY ManagerName