2017-08-07 49 views
1


選擇DateTime不在SQL

我有如下表:

oDateTime    pvalue 
2017-06-01 00:00:00 70 
2017-06-01 01:00:00 65 
2017-06-01 02:00:00 90 
ff. 
2017-08-01 08:00:00 98 

oDateTime字段是每小時的數據是不可能有重複的值。

我的問題是,我怎麼知道oDateTime數據是否正確?我的意思是,我需要確保數據不會跳轉?它應該始終是「小時」的基礎。

我錯過了日期嗎?我錯過了時間嗎?

請指教。謝謝。

+1

預期結果是什麼?你想顯示失蹤的時間? –

+2

計算每個「日期」的記錄數。每個日期應該有24個。 – Incognito

+0

@FelixPamittan,是的,這就是我的意思。 – Haminteu

回答

2

基於this answer,你可以得到丟失的時間形成的表MyLogTable這樣的:

DECLARE @StartDate DATETIME = '20170601', @EndDate DATETIME = '20170801' 

SELECT DATEADD(hour, nbr - 1, @StartDate) 
FROM (SELECT ROW_NUMBER() OVER (ORDER BY c.object_id) AS Nbr 
      FROM  sys.columns c 
     ) nbrs 
WHERE nbr - 1 <= DATEDIFF(hour, @StartDate, @EndDate) AND 
NOT EXISTS (SELECT 1 FROM MyLogTable WHERE DATEADD(hour, nbr - 1, @StartDate)= oDateTime) 

如果您需要檢查週期較長,你可以添加CROSS JOIN這樣

FROM  sys.columns c 
CROSS JOIN sys.columns c1 

它使您能夠在一個查詢中檢查多於cca一千條記錄(sysccolumn表的行數)。

+2

這裏的危險是你需要在sys.columns中有足夠的行來獲得所有的時間。對於示例中的日期,即1465年。如果您缺少它(如我的演示服務器),則可以添加另一個交叉連接。 –

0

也許你正在尋找?這將返回日期爲計數< 24 - 這表示「跳」

;WITH datecount 
     AS (SELECT CAST(oDateTime AS DATE) AS [date] , 
        COUNT(CAST(oDateTime AS DATE)) AS [count] 
      FROM  @temp 
      GROUP BY (CAST(oDateTime AS DATE)) 
     ) 
SELECT * 
FROM datecount 
WHERE [count] < 24; 

編輯:既然你改變了需求「如何知道是否有缺失」到「什麼是失蹤」,這裏是一個更新查詢。

DECLARE @calendar AS TABLE (oDateTime DATETIME) 
DECLARE @min DATETIME = (SELECT MIN([oDateTime]) FROM @yourTable) 
DECLARE @max DATETIME = (SELECT MAX([oDateTime]) FROM @yourTable) 

WHILE (@min <= @max) 
    BEGIN 
     INSERT INTO @calendar 
     VALUES (@min); 

     SET @min = DATEADD(hh, 1, @min); 
    END; 

SELECT t1.[oDateTime] 
FROM @calendar t1 
     LEFT JOIN @yourTable t2 ON t1.[oDateTime] = t2.[oDateTime] 
GROUP BY t1.[oDateTime] 
HAVING COUNT(t2.[oDateTime]) = 0; 

我第一次創建基於您的MAX和MIN DATETIME一個小時日曆,然後與你的實際表,日曆,以找出是否有一個「跳」。

+0

謝謝,我怎麼知道我沒有錯過日期? – Haminteu

+0

@Haminteu我剛剛編輯了我的答案。希望這可以幫助! –

0

由於您的表沒有任何唯一的id號,請使用row_number()獲取cte中的行號,然後使用行id和next id執行自我內部聯接,相應地獲取oDateTime的差異,這正好顯示出哪一行不爲1小時

;with cte(oDateTime,pValue,Rid) 
As 
(
    select *,row_number() over(order by oDateTime) from [YourTableName] t1 
) 
select *,datediff(HH,c1.oDateTime,c2.oDateTime) as HourDiff from cte c1 
inner join cte c2 
on c1.Rid=c2.Rid-1 where datediff(HH,c1.oDateTime,c2.oDateTime) >1 
+0

謝謝,我如何知道我沒有錯過日期? – Haminteu

0

你可以使用DENSE_RANK()的時間差在一天編號的時間從1到24,然後,所有你需要做的是檢查一天中最高排名是否爲24。如果每小時至少有一個條目,則密集排名的最大值將爲24.

使用以下查詢可以查找缺少oDateTime的日期。

SELECT [date] 
FROM 
(
    SELECT * 
    , CAST(oDateTime AS DATE) AS [date] 
    , DENSE_RANK() OVER(PARTITION BY CAST(oDateTime AS DATE) ORDER BY DATEPART(HOUR, oDateTime)) AS rank_num 
    FROM Test 
) AS t 
GROUP BY [date] 
HAVING(MAX(rank_num) != 24); 

如果你需要驗證的oDateTime的每一行,你可以做自聯接根據等級和獲得的這個小時每個oDateTime。

+0

謝謝,我如何知道我沒有錯過日期? – Haminteu

+0

由於錯過了連續的一天,您的預期輸出是多少?你想要在一個月,一年中缺少的日子,還是想要在最早和最近的日期之間錯過幾個月?請舉一個例子。 – Shiblu

+0

我需要列出所有缺少的日期和時間。 – Haminteu