联合或不联合

To UNION or Not to UNION

我目前运行遇到了我的 UNION 子句的问题。我想弄清楚我每天要导入多少订单。问题是,我有两个 tables,这些订单存储在 OLDORDERHEADER 和 ORDERHEADER 中。订单完成后,它从 ORDERHEADER table 移动到 OLD。两者都有完全相同的列,所以我想我会使用 UNION 子句并且没问题。好吧,一旦我 运行 我的查询,它会打印两行,相同的日期和不同的数量。这是意料之中的,我只想将它们组合成一行,然后将每个小时的数量相加。 这是我正在处理的内容:

SELECT CONVERT(varchar(8),recvtime,1) AS 'Day', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 0 THEN 1 ELSE 0 END) AS '12AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 1 THEN 1 ELSE 0 END) AS '1AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 2 THEN 1 ELSE 0 END) AS '2AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 3 THEN 1 ELSE 0 END) AS '3AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 4 THEN 1 ELSE 0 END) AS '4AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 5 THEN 1 ELSE 0 END) AS '5AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 6 THEN 1 ELSE 0 END) AS '6AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 7 THEN 1 ELSE 0 END) AS '7AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 8 THEN 1 ELSE 0 END) AS '8AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 9 THEN 1 ELSE 0 END) AS '9AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 10 THEN 1 ELSE 0 END) AS '10AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 11 THEN 1 ELSE 0 END) AS '11AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 12 THEN 1 ELSE 0 END) AS '12PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 13 THEN 1 ELSE 0 END) AS '1PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 14 THEN 1 ELSE 0 END) AS '2PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 15 THEN 1 ELSE 0 END) AS '3PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 16 THEN 1 ELSE 0 END) AS '4PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 17 THEN 1 ELSE 0 END) AS '5PM',
SUM(CASE WHEN DATEPART(hour,recvtime) = 18 THEN 1 ELSE 0 END) AS '6PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 19 THEN 1 ELSE 0 END) AS '7PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 20 THEN 1 ELSE 0 END) AS '8PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 21 THEN 1 ELSE 0 END) AS '9PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 22 THEN 1 ELSE 0 END) AS '10PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 23 THEN 1 ELSE 0 END) AS '11PM'

FROM MCK_HVS.OLDORDERHEADER WITH(NOLOCK)

WHERE CAST(recvtime as DATE) = CAST(GETDATE() as DATE)

GROUP BY CONVERT(varchar(8),recvtime,1)

UNION

SELECT CONVERT(varchar(8),recvtime,1) AS 'Day', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 0 THEN 1 ELSE 0 END) AS '12AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 1 THEN 1 ELSE 0 END) AS '1AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 2 THEN 1 ELSE 0 END) AS '2AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 3 THEN 1 ELSE 0 END) AS '3AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 4 THEN 1 ELSE 0 END) AS '4AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 5 THEN 1 ELSE 0 END) AS '5AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 6 THEN 1 ELSE 0 END) AS '6AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 7 THEN 1 ELSE 0 END) AS '7AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 8 THEN 1 ELSE 0 END) AS '8AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 9 THEN 1 ELSE 0 END) AS '9AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 10 THEN 1 ELSE 0 END) AS '10AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 11 THEN 1 ELSE 0 END) AS '11AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 12 THEN 1 ELSE 0 END) AS '12PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 13 THEN 1 ELSE 0 END) AS '1PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 14 THEN 1 ELSE 0 END) AS '2PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 15 THEN 1 ELSE 0 END) AS '3PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 16 THEN 1 ELSE 0 END) AS '4PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 17 THEN 1 ELSE 0 END) AS '5PM',
SUM(CASE WHEN DATEPART(hour,recvtime) = 18 THEN 1 ELSE 0 END) AS '6PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 19 THEN 1 ELSE 0 END) AS '7PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 20 THEN 1 ELSE 0 END) AS '8PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 21 THEN 1 ELSE 0 END) AS '9PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 22 THEN 1 ELSE 0 END) AS '10PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 23 THEN 1 ELSE 0 END) AS '11PM'

FROM MCK_HVS.ORDERHEADER WITH(NOLOCK)

WHERE CAST(recvtime as DATE) = CAST(GETDATE() as DATE)

GROUP BY CONVERT(varchar(8),recvtime,1)

ORDER BY CONVERT(varchar(8),recvtime,1)desc

试试这个。

SELECT
    DAY,
    SUM(12AM) AS [12AM]
    .
    .
    .
    .
    .
    .
FROM (
SELECT CONVERT(varchar(8),recvtime,1) AS 'Day', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 0 THEN 1 ELSE 0 END) AS '12AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 1 THEN 1 ELSE 0 END) AS '1AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 2 THEN 1 ELSE 0 END) AS '2AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 3 THEN 1 ELSE 0 END) AS '3AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 4 THEN 1 ELSE 0 END) AS '4AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 5 THEN 1 ELSE 0 END) AS '5AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 6 THEN 1 ELSE 0 END) AS '6AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 7 THEN 1 ELSE 0 END) AS '7AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 8 THEN 1 ELSE 0 END) AS '8AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 9 THEN 1 ELSE 0 END) AS '9AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 10 THEN 1 ELSE 0 END) AS '10AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 11 THEN 1 ELSE 0 END) AS '11AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 12 THEN 1 ELSE 0 END) AS '12PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 13 THEN 1 ELSE 0 END) AS '1PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 14 THEN 1 ELSE 0 END) AS '2PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 15 THEN 1 ELSE 0 END) AS '3PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 16 THEN 1 ELSE 0 END) AS '4PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 17 THEN 1 ELSE 0 END) AS '5PM',
SUM(CASE WHEN DATEPART(hour,recvtime) = 18 THEN 1 ELSE 0 END) AS '6PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 19 THEN 1 ELSE 0 END) AS '7PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 20 THEN 1 ELSE 0 END) AS '8PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 21 THEN 1 ELSE 0 END) AS '9PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 22 THEN 1 ELSE 0 END) AS '10PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 23 THEN 1 ELSE 0 END) AS '11PM'

FROM MCK_HVS.OLDORDERHEADER WITH(NOLOCK)

WHERE CAST(recvtime as DATE) = CAST(GETDATE() as DATE)

GROUP BY CONVERT(varchar(8),recvtime,1)

UNION

SELECT CONVERT(varchar(8),recvtime,1) AS 'Day', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 0 THEN 1 ELSE 0 END) AS '12AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 1 THEN 1 ELSE 0 END) AS '1AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 2 THEN 1 ELSE 0 END) AS '2AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 3 THEN 1 ELSE 0 END) AS '3AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 4 THEN 1 ELSE 0 END) AS '4AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 5 THEN 1 ELSE 0 END) AS '5AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 6 THEN 1 ELSE 0 END) AS '6AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 7 THEN 1 ELSE 0 END) AS '7AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 8 THEN 1 ELSE 0 END) AS '8AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 9 THEN 1 ELSE 0 END) AS '9AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 10 THEN 1 ELSE 0 END) AS '10AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 11 THEN 1 ELSE 0 END) AS '11AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 12 THEN 1 ELSE 0 END) AS '12PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 13 THEN 1 ELSE 0 END) AS '1PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 14 THEN 1 ELSE 0 END) AS '2PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 15 THEN 1 ELSE 0 END) AS '3PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 16 THEN 1 ELSE 0 END) AS '4PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 17 THEN 1 ELSE 0 END) AS '5PM',
SUM(CASE WHEN DATEPART(hour,recvtime) = 18 THEN 1 ELSE 0 END) AS '6PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 19 THEN 1 ELSE 0 END) AS '7PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 20 THEN 1 ELSE 0 END) AS '8PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 21 THEN 1 ELSE 0 END) AS '9PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 22 THEN 1 ELSE 0 END) AS '10PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 23 THEN 1 ELSE 0 END) AS '11PM'

FROM MCK_HVS.ORDERHEADER WITH(NOLOCK)

WHERE CAST(recvtime as DATE) = CAST(GETDATE() as DATE)

GROUP BY CONVERT(varchar(8),recvtime,1)) AS [SOURCE]

ORDER BY 1 desc

无需将整个查询写两次,您可以将联合用作派生 table(或 cte)并仅进行一次分组和求和:

;WITH CTE AS
(
    SELECT recvtime
    FROM MCK_HVS.OLDORDERHEADER WITH(NOLOCK)
    WHERE CAST(recvtime as DATE) = CAST(GETDATE() as DATE)

    UNION 

    SELECT recvtime
    FROM MCK_HVS.ORDERHEADER WITH(NOLOCK)
    WHERE CAST(recvtime as DATE) = CAST(GETDATE() as DATE)
)    

SELECT CONVERT(varchar(8),recvtime,1) AS 'Day', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 0 THEN 1 ELSE 0 END) AS '12AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 1 THEN 1 ELSE 0 END) AS '1AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 2 THEN 1 ELSE 0 END) AS '2AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 3 THEN 1 ELSE 0 END) AS '3AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 4 THEN 1 ELSE 0 END) AS '4AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 5 THEN 1 ELSE 0 END) AS '5AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 6 THEN 1 ELSE 0 END) AS '6AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 7 THEN 1 ELSE 0 END) AS '7AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 8 THEN 1 ELSE 0 END) AS '8AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 9 THEN 1 ELSE 0 END) AS '9AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 10 THEN 1 ELSE 0 END) AS '10AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 11 THEN 1 ELSE 0 END) AS '11AM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 12 THEN 1 ELSE 0 END) AS '12PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 13 THEN 1 ELSE 0 END) AS '1PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 14 THEN 1 ELSE 0 END) AS '2PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 15 THEN 1 ELSE 0 END) AS '3PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 16 THEN 1 ELSE 0 END) AS '4PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 17 THEN 1 ELSE 0 END) AS '5PM',
SUM(CASE WHEN DATEPART(hour,recvtime) = 18 THEN 1 ELSE 0 END) AS '6PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 19 THEN 1 ELSE 0 END) AS '7PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 20 THEN 1 ELSE 0 END) AS '8PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 21 THEN 1 ELSE 0 END) AS '9PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 22 THEN 1 ELSE 0 END) AS '10PM', 
SUM(CASE WHEN DATEPART(hour,recvtime) = 23 THEN 1 ELSE 0 END) AS '11PM'

FROM CTE 
GROUP BY CONVERT(varchar(8),recvtime,1)
ORDER BY CONVERT(varchar(8),recvtime,1) DESC

http://sqlfiddle.com/#!6/defd2/9

 SELECT COUNT(ID), CASE WHEN HOUR < 12 THEN CONVERT(VARCHAR(2),HOUR) + 'AM' 
                ELSE CONVERT(VARCHAR(2),HOUR-12) + 'PM' END 
   FROM (
          SELECT id, DATEPART(hour,recvtime) AS HOUR FROM ORDERHEADER 
              UNION 
          SELECT id, DATEPART(hour,recvtime) AS HOUR FROM oldORDERHEADER ) A
     GROUP BY A.HOUR

您也可以考虑 PIVOT 以获得更简洁的语法。

我发现 UNION 的使用很可疑,我假设您实际上也需要 UNION ALL

WITH CombinedOrderHeader
     AS (SELECT recvtime
         FROM   ORDERHEADER
         UNION ALL
         SELECT recvtime
         FROM   oldORDERHEADER),
     PvtSource(htt, Day)
     AS (SELECT FORMAT(recvtime, 'htt'),
                CONVERT(VARCHAR(8), recvtime, 1)
         FROM   CombinedOrderHeader
         WHERE  recvtime >= CAST(GETDATE() AS DATE)
                AND recvtime < DATEADD(DAY, 1, CAST(GETDATE() AS DATE)))
SELECT *
FROM   PvtSource PIVOT (COUNT(htt) FOR htt IN ([12AM], [1AM], [2AM], [3AM], [4AM], [5AM], 
                                               [6AM], [7AM], [8AM], [9AM], [10AM], [11AM], 
                                               [12PM], [1PM], [2PM], [3PM], [4PM], [5PM], 
                                               [6PM], [7PM], [8PM], [9PM], [10PM], [11PM] 
                                             )) P