2011-05-22 125 views
1

需要您的帮助来解决一个问题。帮助困难的'group by'条款

我有一个表Managers (ManagerId, ManagerName)

我有一个表Statuses (StatusId, StatusName)
(有没有在该表中约10状态)

我有一个表Clients (ClientId, ClientName, ManagerId, StatusId, WhenAdded)
WhenAdded是DateTime类型)

很明显,字段'ManagerId' refe rs到表'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。

回答

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添加状态列arbritrary号(不只是SQL Server),因为它是一个固定的列输出。你不得不更改状态查询,除非您在客户端

编辑解决这个问题,评论后

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 
+0

GBN,没有对管理者有什么客户在一段时间? – 2011-05-22 11:55:41

+0

一个完整的解决方案 – 2011-05-23 00:25:14

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