2016-08-02 5 views
0

私は以下のようなSQL文を持っており、D.DatalogValueに値がなく、NULLまたはゼロの値として表示されない分単位でデータをチェックしたいとしますどちらか。以下の出力結果のサンプルは、createdDateが見つからないと表示されます(2016-06-01 00:32:29)。分単位のSQLでの不足時間のチェック

SELECT 
    A.DefID, A.ObjID, 
    C.ObjName, C.Dev_ID, 
    A.Pro_ID, A.ArrayIndex, 
    A.DefType, A.TObjID, A.DimeId, A.DefId, 
    D.DatalogValue, D.PanelDt, D.CreatedDate 
FROM 
    Table A, Table C, Table D 
WHERE 
    A.ObjID = C.ObjID 
    AND C.ObjID = '2627' 
    AND A.DefID = D.DefID 
    AND D.CreatedDate BETWEEN '2016-06-01' AND '2016-06-02' 
ORDER BY 
    C.ObID,C.ObjName; 

サンプルデータ:

Create Date    DatalogValue 
------------------------------------- 
2016-06-01 00:29:29  0.01 
2016-06-01 00:30:29  0.02 
2016-06-01 00:31:29  0.03 

2016-06-01 00:33:29  0.04 

ソリューション提供を使用することにより、私は、SQLステートメントを出ているが、それはまだないことは、私が欲しいの結果を表示しないように。私は以下のように間違った私のコードをやっている部分私はわからない:

DECLARE @StartDate DATETIME = '2016-07-01'; 
DECLARE @EndDate DATETIME = '2016-07-31'; 

WITH Check_Dates AS (
SELECT @StartDate [Date] 
UNION ALL 
SELECT DATEADD(MINUTE, 1, [Date]) FROM Check_Dates 
WHERE [Date] < DATEADD(DAY, 1, @EndDate) 
) 

SELECT 
FORMAT(d.Date, 'yyyy-MM-dd HH:mm') [Created Date] 

FROM Check_Dates d 
WHERE 
NOT EXISTS(
SELECT 
Format(D.CreatedDate, 'yyyy-MM-dd HH:mm')as created_dt 

FROM TABLE A 
,TABLE C 
,TABLE D 
WHERE A.ObjID=C.ObjID 
AND C.ObjID IN('3915') 
AND A.DefID=D.DefID 
AND D.CreatedDate BETWEEN '2016-07-01' AND '2016-08-01' 
) 

OPTION (MAXRECURSION 0); 
+1

外部結合が必要な場合や、外部結合を持つ 'times'テーブルが必要な場合 - サンプルデータと期待される結果(場合によってはテーブル構造)がなくても言い難い。 – sgeddes

+0

@sgeddesこんにちは私はサンプルデータを投稿しました。私が直面している問題は、ゼロを挿入しなかったか、またはそれをスキップするよう指示したので、表示されなかった分を示す必要があるからです。 – user1391079

+0

一定間隔内のすべての分を含む表を作成します。完全修飾された分でそれに対する外部結合。基準日はあるがデータはない結果のみを取ります。 –

答えて

0

ソリューションがあなたの元のクエリにこれらLEFT JOINその後、DATETIMEのリストを作成するために、CTEを使用することです。 GoogleのDimDateやDimTimeの代わりに(コメントに記載されているように)テーブルのペアを作成することもできます。 (未テスト)のような

何か:

DECLARE @StartDate DATETIME = '2016-06-01'; 
DECLARE @EndDate DATETIME = '2016-06-02'; 

WITH Dates AS (
    SELECT @StartDate [Date] 
    UNION ALL 
    SELECT DATEADD(SECOND, 1, [Date]) FROM Dates 
    WHERE [Date] < DATEADD(DAY, 1, @EndDate) 
) 
SELECT 
d.Date [Created Date] 
,COALESCE(Qry.DatalogValue, 0) DatalogValue 
FROM Dates d 
LEFT JOIN (
    Your query goes here 
) Qry 
ON d.Date = Qry.CreatedDate 
OPTION (MAXRECURSION 0) 
+0

こんにちは、私には9行目で構文エラーが出てくれてありがとうございます。私が修正した後は、それが動作しているかどうかを知ることができます – user1391079

+0

D.DatalogValueに何を置くべきですか? – user1391079

+0

を共有するよう心がけてください申し訳ありませんが、それはあなたのサブクエリで選択している値です。答えを更新します。 –

0

あなたのソリューションは、私には非常に危険と思われます。あなたは秒を比較するべきですか?私は分に切り詰めるだろう。より堅牢なソリューションを提案します。

WITH Dates AS 
(--Your dates and values 
    SELECT * FROM (VALUES 
    ('2016-06-01 00:29:29', 0.01), 
    ('2016-06-01 00:30:29', 0.02), 
    ('2016-06-01 00:31:29', 0.03), 
    ('2016-06-01 00:33:29', 0.04)--,('2016-06-01 01:00:28', 0.05) 
    ) T(CreateDate, CatalogValues) 
), Minute10 AS --Generate numbers from 0-999999 
(
    SELECT * FROM (VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(0)) T1(Value) 
), Minute1000 AS 
(
    SELECT M1.Value FROM Minute10 M1 CROSS JOIN Minute10 M2 CROSS JOIN Minute10 
), Minute1000000 AS 
(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1))-1 Value 
    FROM Minute1000 
    CROSS JOIN Minute1000 M2 
), RangeValues AS --for simplicity, min and max values from dates 
(
    SELECT DATEADD(MINUTE, DATEDIFF(MINUTE, 0, MIN(CreateDate)), 0) MinDate, 
      DATEADD(MINUTE, DATEDIFF(MINUTE, 0, MAX(CreateDate)), 0) MaxDate 
    FROM Dates 
) 
SELECT TOP(1+DATEDIFF(MINUTE, (SELECT MinDate FROM RangeValues), (SELECT MaxDate FROM RangeValues))) 
DATEADD(MINUTE,Value,MinDate) ExpectedDate, CreateDate, CatalogValues 
FROM Minute1000000 
CROSS APPLY (SELECT MinDate FROM RangeValues) T 
LEFT JOIN Dates ON DATEADD(MINUTE,Value,MinDate)=DATEADD(MINUTE, DATEDIFF(MINUTE, 0, CreateDate), 0) 

すべての日付は分に切り捨てられます。番号生成部分を削除してクエリを簡単に行うことができます(番号はユーティリティテーブルに置くことができます。必要な場合は1440の値)。最小値と最大値は事前に計算できます。

これは以下の出力をもたらす(範囲MinDateプロパティ+ 999999分を処理することができ、簡単に拡張することができる):

ExprectedDate    CreateDate   CatalogValues 
2016-06-01 00:29:00.000 2016-06-01 00:29:29 0.01 
2016-06-01 00:30:00.000 2016-06-01 00:30:29 0.02 
2016-06-01 00:31:00.000 2016-06-01 00:31:29 0.03 
2016-06-01 00:32:00.000 NULL     NULL 
2016-06-01 00:33:00.000 2016-06-01 00:33:29 0.04 

説明:

日付は単にソース表です。テーブルMinute10 .. Minute1000000は、0から999999までの数字を生成します(10がクロスされた10 = 100,100がクロス結合されたx3 = 100^3 = 1000000)。最後のテーブルのレコードは連続した値を取得するために番号が付けられます。 。。すべての1000000個の値を評価するからRangeValuesを簡単にするために、MAXとMINの日付が含まれてい

アルゴリズム:

あなたがMAX日の毎分をMIN日からレコードを必要とするので、あなたは避けるようにTOP DATETIFF(MINUTE,MIN,MAX)+1記録(+1を評価すべての必要なテーブルが結合されます(CROSS APLLYはすべてのレコードにMIN列を追加します)、期待される日付はMINの日付+逐次値(分)として計算されます。 ast結合、LEFT 1、毎分生成された日付をソース表と照合します。一致があれば、レコードが追加(結合)されます。一致するものがない場合、NULLが追加されます。注意 `DATEADD(MINUTE、DATEDIFF(MINUTE、0、@someDate)、0) 'は、日付から秒を切り捨てます。

+0

こんにちは、あなたの解決策は少し複雑です私はあなたが詳細に説明したいと思いますか? – user1391079

関連する問題