我正在尝试使用这四个简化表编写查询:
组织
(pk)组织ID
单位名称
(fk)ParentOrganizationID
人员
(pk)人员ID
(fk)组织ID
名称
事件
(pk)EventID
事件名称
事件日志
(pk)人员ID
(pk)EventID
TimeOfParticipation
我想创建一个查询,该查询将eventID和organizationID作为参数,并返回一个表,该表返回组织的所有名称,组织和子组织中的总数以及事件中的参与者总数对于组织和它的孩子。返回的示例可能是:
OrganizationName | TotalNumberInOrganization | TotalParticipatingInEvent
TopOrganization | 200 | 150
SecondTier1 | 150 | 100
Tier1Child | 50 | 50
Tier1Child2 | 50 | 25
SecondTier2 | 25 | 25
最高组织是其所有子项的总和,SecondTier1和SecondTier2,以及它们本身。 SecondTier1是它的所有子节点Teir1Child和Tier1Child2的总和。这将继续计算所有的孩子和总数。
我知道如何使用递归CTE返回一个条目,例如只是顶级组织的总数,但我不知道如何获得所有组织及其子组的总数。任何帮助将不胜感激。
这里要求的是我用来返回关于组织的单行的过程。
出于某种原因,如果我在UNION中添加“U”,它会引发网络错误,并且不允许我对其进行编辑。
@OrganizationID uniqueidentifier
@EventID uniqueidentifier
WITH OrganizationList(OrganizationID) AS
(SELECT Organization.OrganizationID
FROM Organization
WHERE OrganizationID = @OrganizationID
NION ALL
SELECT Organization.OrganizationID
FROM Organization
INNER JOIN OrganizationList ON Organization.ParentOrganizationID = OrganizationList.OrganizationID)
SELECT OrganizationAbbreviation,
(SELECT COUNT(*)
FROM Personnel
WHERE Personnel.OrganizationID IN (SELECT OrganizationID FROM OrganizationList))
AS OrganizationTotal,
(SELECT COUNT(*)
FROM Personnel
INNER JOIN EventLog ON EventLog.PersonnelID = Personnel.PersonnelID
WHERE Personnel.OrganizationID IN (SELECT OrganizationID FROM OrganizationList)
AND EventLog.EventID = @EventID)
AS TotalPresent
FROM Organization
WHERE OrganizationID = @OrganizationID
答案 0 :(得分:2)
我认为这对你有用:
WITH OrganizationTree (RootOrganizationID, OrganizationID)
AS
(
--Anchor
SELECT O.OrganizationID, O.OrganizationID
FROM Organization O
UNION ALL
--Recurse
SELECT T.RootOrganizationID, O.OrganizationID
FROM OrganizationTree T
JOIN Organization O
ON O.ParentOrganizationId = T.OrganizationID
)
--execute
SELECT P.OrganizationName,
SUM(ISNULL(PPL.NumberInOrganization, 0)) AS TotalNumberInOrganization,
SUM(ISNULL(EVT.NumberParticipatingInEvent, 0)) AS TotalNumberParticipatingInEvent
FROM OrganizationTree T
JOIN Organization P
ON T.RootOrganizationID = P.OrganizationID
LEFT
JOIN
(
SELECT P.OrganizationID,
COUNT(*) AS NumberInOrganization
FROM Personnel P
GROUP BY P.OrganizationID
) PPL
ON PPL.OrganizationID = T.OrganizationID
LEFT
JOIN
(
SELECT P.OrganizationID,
COUNT(*) AS NumberParticipatingInEvent
FROM EventLog EL
JOIN Personnel P
ON EL.PersonnelID = P.PersonnelID
GROUP BY P.OrganizationID
) EVT
ON EVT.OrganizationID = T.OrganizationID
GROUP BY T.RootOrganizationID, P.OrganizationName
如果您需要像示例输出中那样使用缩进,那么这应该有效:
WITH OrganizationTree (RootOrganizationID, OrganizationID)
AS
(
--Anchor
SELECT O.OrganizationID, O.OrganizationID
FROM Organization O
UNION ALL
--Recurse
SELECT T.RootOrganizationID, O.OrganizationID
FROM OrganizationTree T
JOIN Organization O
ON O.ParentOrganizationId = T.OrganizationID
)
--execute
SELECT SPACE(L.OrganizationLevel) + P.OrganizationName AS FormattedOrganizationName,
P.OrganizationName,
SUM(ISNULL(PPL.NumberInOrganization, 0)) AS TotalNumberInOrganization,
SUM(ISNULL(EVT.NumberParticipatingInEvent, 0)) AS TotalNumberParticipatingInEvent
FROM OrganizationTree T
JOIN
(
SELECT L.OrganizationID,
(COUNT(*) - 1) AS OrganizationLevel
FROM OrganizationTree L
GROUP BY L.OrganizationID
) L
ON T.RootOrganizationID = L.OrganizationID
JOIN Organization P
ON T.RootOrganizationID = P.OrganizationID
LEFT
JOIN
(
SELECT P.OrganizationID,
COUNT(*) AS NumberInOrganization
FROM Personnel P
GROUP BY P.OrganizationID
) PPL
ON PPL.OrganizationID = T.OrganizationID
LEFT
JOIN
(
SELECT P.OrganizationID,
COUNT(*) AS NumberParticipatingInEvent
FROM EventLog EL
JOIN Personnel P
ON EL.PersonnelID = P.PersonnelID
GROUP BY P.OrganizationID
) EVT
ON EVT.OrganizationID = T.OrganizationID
GROUP BY T.RootOrganizationID, L.OrganizationLevel, P.OrganizationName