简体   繁体   中英

SQL Server - UNION ALL

I'm new to SQL development and I need to do UNION on two select statements. Below is a sample query. The Join tables & conditions, where criteria, columns names and everything is the same in both the select statements except the the primary tables after the FROM clause. I just wanted to know if there is a way to have a single static select query, instead of repeating the same query twice for the UNION (without going for a dynamic query).

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

OK... What I posted earlier was a sample query and I've updated the sample to my actual query to make it more clear. It's just the primary tables that are different. My requirement is that - after doing UNION ALL, I need to sum the aggregate columns in the final result, grouping by ProgramId.

I would probably first use UNION for the Client and LegacyClient tables as a derived table and then perform the 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

Using testFunction() twice isn't really necessary (unless null is one of the outputs.) 布尔逻辑

You might also prefer to filter on ClientId outside of the union. I'm guess your purpose in rewriting it to avoid the duplicated logic. You might still want to see which one is better handled by the optimizer.

Also, I used a UNION ALL . I'm thinking you imagine only one result from one of the two tables. As you originally wrote it that count column is going to factor into the union.

Counting on ClientId seems odd. So does having a parameter named @ClientId that doesn't seem to match up with the ClientId column.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM