2014-10-20 82 views
0

我正在計數(按小時計)數據庫中的條目數。我已經成功編寫了一個按小時計算的查詢,但它省略了零個小時的查詢。我需要結果包括零。我環顧了網絡,發現了很多建議。我創建了一個視圖,其中包含一個包含日期時間條目的列。我試過將主表連接到這個視圖,並且沒有連接,我得到了相同的結果。仍然沒有零。想知道如何讓這個查詢返回零。我正在使用MS SQL 2008 R2。有什麼建議麼?按小時計算行數幷包含零

declare @limit datetime; 
use InputArchive 
set @limit = current_timestamp; 
set @limit = DATEADD(hour, -72, @limit); 
SELECT DATEADD(hour, datediff(hour, 0, ArchivedItems.RecordCreated), 0) as TimeHour, COUNT(ISNULL((ArchivedItems.RecordCreated),' ')) as NumPerHour 
FROM ArchivedItems 
LEFT OUTER JOIN vw_hoursalot 
ON vw_hoursalot.dtHr = ArchivedItems.RecordCreated 
where InputTypeId = 5 or InputTypeId = 6 or InputTypeId = 8 and (ArchivedItems.RecordCreated >= @limit) 
Group BY DATEADD(hour, Datediff(hour, 0, ArchivedItems.RecordCreated), 0) 
order by DATEADD(hour, datediff(hour, 0, ArchivedItems.RecordCreated), 0) desc 
option (MAXRECURSION 0) 

更新:我改變了看法hoursalot是按小時 我很抱歉,但我不知道你所說全視角SQL的意思。

我不能把任何兩岸信息從archivedItems表出於法律原因,但RecordCreated列是海峽戳即「2013年4月5日14:09:59.167」

+0

無論是顛倒順序,或更改條件的權利OUTER JOIN - 你需要這個查詢來開始全部小時的列表,然後連接到另一側。 – AHiggins 2014-10-20 19:41:16

+0

正確的外部聯接和交換命令兩個都沒有工作,他們都返回相同的東西,這是兩行,每個結果一個計數。應該有兩個以上的方式 – BVT 2014-10-20 19:46:18

回答

0

嘗試把vw_hoursalot作爲條件中最左邊的表 - 這意味着將返回視圖中的所有行,無論是否找到ArchivedHours中的對應記錄。

我再次編輯過 - 這次我花時間模擬了一些虛擬數據,並且我意識到代碼中的問題(包括我的和你的)是ArchivedItems.RecordCreated列被用作過濾器WHERE條件。因此,只會返回具有RecordCreated值的記錄。

我已經將該條件移至JOIN,並針對我嘲笑的一些非常基本的數據運行下面的查詢。假設您的vw_HoursALot視圖返回編號爲0-23的二十四個整數,則應該爲您提供您正在查找的數據。

請注意:我做了InputTypeIDArchivedItems的假設。

WITH -- I used these two CTEs as my dummy data, based on the information in your post 
    vw_HoursALot AS 
     (
     SELECT 1 dtHr UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION 
     SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10 UNION 
     SELECT 11 UNION SELECT 12 UNION SELECT 13 UNION SELECT 14 UNION SELECT 15 UNION 
     SELECT 16 UNION SELECT 17 UNION SELECT 18 UNION SELECT 19 UNION SELECT 20 UNION 
     SELECT 21 UNION SELECT 22 UNION SELECT 23 UNION SELECT 0 
    ), 
    ArchivedItems AS 
     (
     SELECT GETDATE() AS RecordCreated, 5 AS InputTypeID 
     UNION SELECT DATEADD(HOUR, -3, GETDATE()), 6 AS InputTypeID 
    ) 


-- this part is actually doing the work 
SELECT 
    vw_HoursALot.dtHr, 
    COUNT(ArchivedItems.RecordCreated) AS NumPerHour 
FROM 
    vw_hoursalot 
    LEFT OUTER JOIN 
    ArchivedItems ON 
     vw_hoursalot.dtHr = DATEPART(hour, ArchivedItems.RecordCreated) AND 
     ArchivedItems.RecordCreated >= DATEADD(hour, -72, GETDATE()) AND 
      (
      InputTypeId = 5 OR 
      InputTypeId = 6 OR 
      InputTypeId = 8 
     ) 
GROUP BY vw_HoursALot.dtHr 
ORDER BY vw_HoursALot.dtHr DESC 
OPTION (MAXRECURSION 0) 
+0

感謝您的快速回復。這不起作用,要麼我看到這樣的結果,時間小時NumPerHour 1 2013-10-28 08:00:00:000 1 2013-10-25 21:00:00:00 1這些都是唯一的我得到兩排。而且應該還有更多。 – BVT 2014-10-20 19:49:36

+0

好吧,我已經嘗試了另一個示例 - 如果這不起作用,請使用完整視圖SQL以及ArchivedItems表中的一些示例數據編輯您的問題。 – AHiggins 2014-10-20 19:51:17

+0

好的我已經更新了我原來的問題 – BVT 2014-10-20 20:19:02

0

這裏是我想出了:

declare @limit datetime; 
declare @BaseTime datetime 
set @BaseTime = '20141020 15:00'; --must be an even hour 
set @limit = DATEADD(hour, -72, @BaseTime); 
print @Basetime 
;WITH 
    D1(N) AS (
      SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
      SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
      SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 
      ), 
    D2(N) AS (SELECT 1 FROM D1 a, D1 b), 
    Numbers AS (SELECT TOP (100) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))-1 AS Number FROM D2), 
    AllHours AS (SELECT DATEADD(hour,numbers.number,@limit) AS hr FROM Numbers), 
    Raw_Data AS (
    SELECT DATEADD(hour,DATEDIFF(hour,@BaseTime,RecordCreated),@BaseTime) AS HourRecorded FROM 
    ArchivedItems 
    WHERE RecordCreated BETWEEN @limit AND @BaseTime 
    AND InputTypeID IN (5,6,8) 
    ) 
SELECT count(Raw_Data.HourRecorded),AllHours.hr 
FROM AllHours left outer join Raw_Data on AllHours.hr = Raw_Data.HourRecorded 
GROUP BY AllHours.hr 
order by AllHours.hr 

這是我用來創建測試數據

;WITH 
    D1(N) AS (
      SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
      SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
      SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 
      ), 
    D2(N) AS (SELECT 1 FROM D1 a, D1 b), 
    D4(N) AS (SELECT 1 FROM D2 a, D2 b), 
    Numbers AS (SELECT TOP (10000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))-1 AS Number FROM D4) 
INSERT INTO ArchivedItems(InputTypeID, RecordCreated) 
SELECT ABS(CAST(CAST(NEWID() AS VARBINARY) % 10 AS INT)), DATEADD(MINUTE, ABS(CAST(CAST(NEWID() AS VARBINARY) % 10000 AS INT)),'20141017') 
FROM Numbers 
--Make sure there is a gap 
DELETE FROM ArchivedItems WHERE RecordCreated BETWEEN '2014-10-20 06:00:00.000' AND '2014-10-20 08:00:00.000' 
+0

其中很大一部分是創建一個動態的小時表。你可以通過預先製作全部或部分內容來縮短它。 – LeeG 2014-10-20 22:13:26