SQL 服务器 - 联合所有
SQL Server - UNION ALL
我是 SQL 开发的新手,我需要对两个 select 语句执行 UNION。下面是一个示例查询。 Join 表和条件,其中条件、列名和所有内容在 select 语句中都是相同的,除了 FROM 子句之后的主表。我只是想知道是否有一种方法可以进行单个静态 select 查询,而不是为 UNION 重复相同的查询两次(无需进行动态查询)。
SELECT Sum(ABC.Intakes) As TotalIntakes, Sum(ABC.ClientTarget) as TotalClientTarget
FROM(
SELECT Sum(tt.IntakesReceived) As Intakes, Sum(tt.ClientTarget) As ClientTarget,
tt.ProgramId
FROM
(SELECT Count(DISTINCT ClientID) As IntakesReceived,
DATEDIFF(MONTH, L.AwardStartDate, L.AwardEndDate)*L.MonthlyClientTarget As ClientTarget,
L.AwardId, L.ProgramId
FROM IntakeCoverageLegacy As L
LEFT JOIN UserRoleEntity URE ON URE.EntityId = L.AwardId
LEFT JOIN CDPUserRole UR ON URE.UserRoleId = UR.Id AND UR.CDPUserId = @UserId
WHERE (@Program IS NULL OR L.ProgramId IN (SELECT ProgramID FROM @ProgramIDList)
AND (ufn_IsInternalUser(@UserId) = 1
OR (ufn_IsInternalUser(@UserId) = 0 AND UR.CDPUserId = @UserId ))
GROUP BY L.AwardId, L.ProgramId) As tt
GROUP BY tt.ProgramId, tt.ProgramName
UNION ALL
SELECT Sum(tt.IntakesReceived) As Intakes, Sum(tt.ClientTarget) As ClientTarget,
tt.ProgramId
FROM
(SELECT Count(DISTINCT C.ClientID) As IntakesReceived,
DATEDIFF(MONTH, C.AwardStartDate, C.AwardEndDate)*L.MonthlyClientTarget As ClientTarget,
C.AwardId, C.ProgramId
FROM IntakeCoverageCDP As C
LEFT JOIN UserRoleEntity URE ON URE.EntityId = L.AwardId
LEFT JOIN CDPUserRole UR ON URE.UserRoleId = UR.Id AND UR.CDPUserId = @UserId
WHERE (@Program IS NULL OR C.ProgramId IN (SELECT ProgramID FROM @ProgramIDList)
AND (ufn_IsInternalUser(@UserId) = 1
OR (ufn_IsInternalUser(@UserId) = 0 AND UR.CDPUserId = @UserId ))
GROUP BY C.AwardId, C.ProgramId) As tt
GROUP BY tt.ProgramId, tt.ProgramName
) As ABC
GROUP BY ABC.ProgramId
好的...我之前发布的是示例查询,我已将示例更新为我的实际查询以使其更加清晰。只是主表不同。我的要求是 - 在执行 UNION ALL 之后,我需要对最终结果中的聚合列求和,按 ProgramId 分组。
我可能会首先使用 UNION
作为 Client
和 LegacyClient
table 作为派生的 table 然后执行 JOIN
s:
SELECT C.AwardId,
C.ProgramName,
COUNT(ClientId) AS Intakes
FROM ( SELECT AwardId,
ProgramName,
Id
FROM Client
WHERE Id = @ClientId
UNION
SELECT AwardId,
ProgramName,
Id
FROM LegacyClient
WHERE Id = @ClientId) C
LEFT JOIN UserRoleEntity URE
ON C.AwardId = URE.EntityId
LEFT JOIN UserRole UR
ON URE.UserRoleId = UR.Id AND UR.CDPUserId = @UserId
WHERE (testFunction(@UserId) = 0
OR (testFunction(@UserId) <> 0 AND UR.CDPUserId = @UserId))
GROUP BY C.AwardId,
C.ProgramName;
SELECT C.AwardId, C.ProgramName, Count(ClientId) as Intakes
FROM
(
SELECT Id, AwardId, ProgramName, ClientId FROM Client UNION ALL
SELECT Id, AwardId, ProgramName, ClientId FROM LegacyClient
) C
LEFT OUTER JOIN UserRoleEntity URE ON C.AwardId = URE.EntityId
LEFT OUTER JOIN UserRole UR ON URE.UserRoleId = UR.Id AND UR.CDPUserId = @UserId
WHERE
C.Id = @ClientId
AND (testFunction(@UserId) = 0 OR UR.CDPUserId = @UserId)
GROUP BY C.AwardId, C.ProgramName
使用 testFunction()
两次并不是真正必要的(除非 null
是输出之一。)
您可能还希望在联盟之外的 ClientId
上进行过滤。我猜你重写它的目的是为了避免重复的逻辑。您可能仍想看看优化器对哪一个处理得更好。
另外,我用了一个UNION ALL
。我在想你想象两个表中的一个只有一个结果。正如您最初写的那样,计数列将纳入并集。
指望 ClientId
似乎很奇怪。一个名为 @ClientId
的参数似乎与 ClientId
列不匹配也是如此。
我是 SQL 开发的新手,我需要对两个 select 语句执行 UNION。下面是一个示例查询。 Join 表和条件,其中条件、列名和所有内容在 select 语句中都是相同的,除了 FROM 子句之后的主表。我只是想知道是否有一种方法可以进行单个静态 select 查询,而不是为 UNION 重复相同的查询两次(无需进行动态查询)。
SELECT Sum(ABC.Intakes) As TotalIntakes, Sum(ABC.ClientTarget) as TotalClientTarget
FROM(
SELECT Sum(tt.IntakesReceived) As Intakes, Sum(tt.ClientTarget) As ClientTarget,
tt.ProgramId
FROM
(SELECT Count(DISTINCT ClientID) As IntakesReceived,
DATEDIFF(MONTH, L.AwardStartDate, L.AwardEndDate)*L.MonthlyClientTarget As ClientTarget,
L.AwardId, L.ProgramId
FROM IntakeCoverageLegacy As L
LEFT JOIN UserRoleEntity URE ON URE.EntityId = L.AwardId
LEFT JOIN CDPUserRole UR ON URE.UserRoleId = UR.Id AND UR.CDPUserId = @UserId
WHERE (@Program IS NULL OR L.ProgramId IN (SELECT ProgramID FROM @ProgramIDList)
AND (ufn_IsInternalUser(@UserId) = 1
OR (ufn_IsInternalUser(@UserId) = 0 AND UR.CDPUserId = @UserId ))
GROUP BY L.AwardId, L.ProgramId) As tt
GROUP BY tt.ProgramId, tt.ProgramName
UNION ALL
SELECT Sum(tt.IntakesReceived) As Intakes, Sum(tt.ClientTarget) As ClientTarget,
tt.ProgramId
FROM
(SELECT Count(DISTINCT C.ClientID) As IntakesReceived,
DATEDIFF(MONTH, C.AwardStartDate, C.AwardEndDate)*L.MonthlyClientTarget As ClientTarget,
C.AwardId, C.ProgramId
FROM IntakeCoverageCDP As C
LEFT JOIN UserRoleEntity URE ON URE.EntityId = L.AwardId
LEFT JOIN CDPUserRole UR ON URE.UserRoleId = UR.Id AND UR.CDPUserId = @UserId
WHERE (@Program IS NULL OR C.ProgramId IN (SELECT ProgramID FROM @ProgramIDList)
AND (ufn_IsInternalUser(@UserId) = 1
OR (ufn_IsInternalUser(@UserId) = 0 AND UR.CDPUserId = @UserId ))
GROUP BY C.AwardId, C.ProgramId) As tt
GROUP BY tt.ProgramId, tt.ProgramName
) As ABC
GROUP BY ABC.ProgramId
好的...我之前发布的是示例查询,我已将示例更新为我的实际查询以使其更加清晰。只是主表不同。我的要求是 - 在执行 UNION ALL 之后,我需要对最终结果中的聚合列求和,按 ProgramId 分组。
我可能会首先使用 UNION
作为 Client
和 LegacyClient
table 作为派生的 table 然后执行 JOIN
s:
SELECT C.AwardId,
C.ProgramName,
COUNT(ClientId) AS Intakes
FROM ( SELECT AwardId,
ProgramName,
Id
FROM Client
WHERE Id = @ClientId
UNION
SELECT AwardId,
ProgramName,
Id
FROM LegacyClient
WHERE Id = @ClientId) C
LEFT JOIN UserRoleEntity URE
ON C.AwardId = URE.EntityId
LEFT JOIN UserRole UR
ON URE.UserRoleId = UR.Id AND UR.CDPUserId = @UserId
WHERE (testFunction(@UserId) = 0
OR (testFunction(@UserId) <> 0 AND UR.CDPUserId = @UserId))
GROUP BY C.AwardId,
C.ProgramName;
SELECT C.AwardId, C.ProgramName, Count(ClientId) as Intakes
FROM
(
SELECT Id, AwardId, ProgramName, ClientId FROM Client UNION ALL
SELECT Id, AwardId, ProgramName, ClientId FROM LegacyClient
) C
LEFT OUTER JOIN UserRoleEntity URE ON C.AwardId = URE.EntityId
LEFT OUTER JOIN UserRole UR ON URE.UserRoleId = UR.Id AND UR.CDPUserId = @UserId
WHERE
C.Id = @ClientId
AND (testFunction(@UserId) = 0 OR UR.CDPUserId = @UserId)
GROUP BY C.AwardId, C.ProgramName
使用 testFunction()
两次并不是真正必要的(除非 null
是输出之一。)
您可能还希望在联盟之外的 ClientId
上进行过滤。我猜你重写它的目的是为了避免重复的逻辑。您可能仍想看看优化器对哪一个处理得更好。
另外,我用了一个UNION ALL
。我在想你想象两个表中的一个只有一个结果。正如您最初写的那样,计数列将纳入并集。
指望 ClientId
似乎很奇怪。一个名为 @ClientId
的参数似乎与 ClientId
列不匹配也是如此。