我已经搞好了好几天。我有经理人表,他们被分配到的站点以及分配给这些站点的种植者。我需要知道经理有多少种植者。管理人员被分配到网站但不是种植者,所以我必须通过这次演练来了解特定经理根据分配给他所拥有的每个网站的种植者有多少种植者。一个站点只有一个种植者。我可以相当容易地获得特定经理的种植者数量,但我想返回一个包含每个经理的种植者数量的表格,我很难过。
我有以下代码:
DECLARE @ManagerID INT
DECLARE @getManagerID CURSOR
SET @getManagerID = CURSOR FOR
SELECT ID
FROM Managers
OPEN @getManagerID
FETCH NEXT
FROM @getManagerID INTO @ManagerID
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT COUNT(Grower) AS NumGrowers
FROM Growers
WHERE Growers.ID IN
(
SELECT sitesg.Grower
FROM SitesG
WHERE SitesG.id IN
(
SELECT SITE
FROM ManagerSites
WHERE ManagerSites.Manager IN
(
SELECT ID
FROM Managers
WHERE ID = @ManagerID
)
)
)
FETCH NEXT
FROM @getManagerID INTO @ManagerID
END
CLOSE @getManagerID
DEALLOCATE @getManagerID
这给了我一堆我可以存储在临时表中的结果,但必须有更好的方法。有什么想法吗?
-Joe
答案 0 :(得分:1)
是的,请丢弃游标和所有嵌套的子查询。这正是联接的目的......
SELECT ManagerID = m.ID, NumGrowers = COUNT(DISTINCT g.ID)
FROM dbo.Managers AS m
INNER JOIN dbo.ManagerSites AS s
ON s.Manager = m.ID
INNER JOIN dbo.SitesG AS sg
ON s.SITE = sg.id
INNER JOIN dbo.Growers AS g
ON sg.Grower = g.ID
GROUP BY m.ID;
事实上,如果你关心的只是ManagerID
,你可以简化这个:
SELECT ManagerID = s.Manager, NumGrowers = COUNT(DISTINCT g.ID)
FROM dbo.ManagerSites AS s
INNER JOIN dbo.SitesG AS sg
ON s.SITE = sg.id
INNER JOIN dbo.Growers AS g
ON sg.Grower = g.ID
GROUP BY s.Manager;
顺便说一句,加入s.Manager = m.ID
和sg.Grower = g.ID
等内容非常困惑。你为什么不把它们在模型中出现的任何地方称为ManagerID
,GrowerID
等等?这肯定会使这些连接更加直观。