2017-07-03 359 views
1

我目前遇到了我的UNION子句的問題。我想知道每天有多少訂單是通過我進口的。問題是,我有兩個表,這些訂單存儲在OLDORDERHEADER和ORDERHEADER中。訂單完成後,它將從ORDERHEADER表移到OLD中。兩者都有相同的確切列,所以我想我會使用UNION子句,並罰款。那麼一旦我運行我的查詢,它會打印兩行,相同的日期和不同的qtys'。這是可以預料的,我只是想將它們合併爲一行,並將每小時的數量總和。 以下是我正在處理的內容:聯盟或不聯盟

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 
+1

因此,將該查詢作爲一個通用表格表達式,然後按小時計算並按天分組。 – xQbert

回答

2

您可能還會考慮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 
+0

樞軸允許我的查詢運行速度快很多,我一定會採取的。我有一個長時間的研究這些方法的夜晚! –

+0

@AlanWillever它可能是'UNION ALL',它負責任何性能優勢,因爲它不花時間查找和刪除重複項。 –

0

試試這個。

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 
3

無需編寫整個查詢兩次,則可以使用工會作爲派生表(或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 
+0

工作完美,我不知道你可以用(帶)查詢。我一定會更多地研究。再次感謝大家。我很感激 –

+0

@AlanWillever在做'GROUP BY'之前'UNION'會刪除重複的東西就是你需要的東西? –

+0

@MartinSmith我認爲在這種情況下工會是更好的選擇,因爲工會都可能會返回真正重複的記錄,我不認爲OP要這樣做。我實際上正在考慮在我的答案中寫下一些關於這方面的內容,但隨後我得出了這個結論。不過,你指出這一點很好,因爲我沒有。 –

0

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 
+0

如果在Count = 0時沒有任何訂單,那麼這將不包括一小時。 –

+0

@mr_eclair,我提議的查詢分兩步執行,首先,UNION將連接來自兩個表的所有結果,直接用id推斷,第二部分是GROUP BY,它將按ID排序訂單的數量。你是對的,它不會爲缺少的時間生成記錄。這可以通過將這個查詢與UDF進行鏈接來生成空閒時間的記錄。 –