2016-09-06 21 views
2

私が作成したクエリはソリューションに適合しません。私は多くのクエリを試しましたが、私が望む結果を得ることができません。SQL Server最大7日間の古いレコードに基づいて結合する

私は、次の表に

CREATE TABLE [dbo].[test](
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [ATC] [varchar](15) NOT NULL, 
    [PID] [varchar](7) NOT NULL, 
    [NAME] [varchar](50) NOT NULL, 
    [REG_DATE] [datetime] NULL, 
    [ACTIVE] [bit] NOT NULL CONSTRAINT [DF_test_ACTIVE] DEFAULT ((1)) 
) ON [PRIMARY] 

例データ

INSERT INTO [dbo].[test] ([ATC],[PID],[NAME],[REG_DATE],[ACTIVE]) 
    VALUES ('A01','123456','TEST1','2016-08-31 00:00:00.000',0); 
    INSERT INTO [dbo].[test] ([ATC],[PID],[NAME],[REG_DATE],[ACTIVE]) 
    VALUES ('A01','123456','TEST2','2016-09-01 00:00:00.000',0); 
    INSERT INTO [dbo].[test] ([ATC],[PID],[NAME],[REG_DATE],[ACTIVE]) 
    VALUES ('A01','123456','TEST3','2016-09-02 00:00:00.000',0); 
    INSERT INTO [dbo].[test] ([ATC],[PID],[NAME],[REG_DATE],[ACTIVE]) 
    VALUES ('A01','123456','TEST4','2016-09-03 00:00:00.000',0); 
    INSERT INTO [dbo].[test] ([ATC],[PID],[NAME],[REG_DATE],[ACTIVE]) 
    VALUES('A01','123456','TEST5','2016-09-06 00:00:00.000',1); 

クエリ例があります。

;WITH CTE AS 
(
    SELECT ROW_NUMBER() OVER (PARTITION BY ATC, PID ORDER BY REG_DATE ASC) AS ROWNUM,* FROM [dbo].[test] 
    WHERE ACTIVE=0 
) 
SELECT DATEDIFF(DAY, d2.REG_DATE, d1.REG_DATE),d1.NAME, d1.REG_DATE AS ACTIVE_REC_DATE, d2.REG_DATE AS NOTACTIVE_REC_DATE, d1.ACTIVE, d2.ACTIVE FROM [dbo].[test] as d1 
LEFT JOIN CTE d2 ON d2.ATC = d1.ATC AND d2.PID = d1.PID 
AND DATEDIFF(DAY, d2.REG_DATE, d1.REG_DATE) <= 7 
WHERE d1.ACTIVE=1 AND d1.PID=123456; 

募集結果:

真のACTIVE列を持つレコード(1 )レコードが存在する場合は、アクティブではない前のレコードのREG_DATEを最大7日以内に含める必要があります。 Like:

(No column name) NAME ACTIVE_REC_DATE NOTACTIVE_REC_DATE ACTIVE ACTIVE 
3 TEST5 2016-09-06 00:00:00.000 2016-08-31 00:00:00.000 1 0 

現在、クエリ結果には7日間に収まるレコードが増えているため、複数のレコードが含まれています。私は最大7日間の古いものになる1レコードに参加する必要があります。

私は昇順でソートするため、最初のレコードを使用して識別できるように、オーバーパーティションでROW_NUMBER()を使用しました。以前のレコードがない場合、または以前のレコードが7日以上経過している場合は機能しません 結合するレコードがない場合、無視されるINNER JOINまたはNULLの日付列

私は明確です私の説明と一緒に。あなたの左にROWNUMにフィルタを追加することにより、PIDのための単一の行を返すことができ

+0

はまた、あなたは、「利用可能な前のレコードまたは前のレコードが7日、その後経過していないがあるときにこれは動作しません」説明してもらえあなたの予想結果テーブル –

+0

を投稿してくださいことはできますか?そのような状況では、結果はどうあるべきですか? –

+0

@SandipPatelまた、私の説明には予期せぬことがあります。それは以下です。結果: – Shift

答えて

1
SELECT DATEDIFF(DAY, d2.REG_DATE, d1.REG_DATE),d1.NAME, d1.REG_DATE AS ACTIVE_REC_DATE, d2.REG_DATE AS NOTACTIVE_REC_DATE, d1.ACTIVE, d2.ACTIVE FROM [dbo].[test] as d1 
OUTER APPLY 
(SELECT TOP 1 T1.* FROM dbo.test t1 WHERE t1.ATC = d1.ATC AND t1.PID = d1.PID and DATEDIFF(DAY, t1.REG_DATE, d1.REG_DATE) <= 7 order by t1.REG_DATE desc) d2 
WHERE d1.ACTIVE=1 AND d1.PID=123456; 
+0

ソート順を昇順に変更して結果が得られるようにする必要がありました。クエリが機能するようですが、特定のシナリオを確認する必要があります。御時間ありがとうございます。前に適用されたことはありません。 – Shift

+1

あなたが最も古いか最新の日付が必要かどうかはわかりませんでしたが、これまでのところ助けになってうれしいです。 – Cato

0

参加:

それは質問から明らかではありません
;WITH CTE AS 
(
    SELECT ROW_NUMBER() OVER (PARTITION BY ATC, PID ORDER BY REG_DATE ASC) AS ROWNUM,* FROM [dbo].[test] 
    WHERE ACTIVE=0 
) 
SELECT DATEDIFF(DAY, d2.REG_DATE, d1.REG_DATE),d1.NAME, d1.REG_DATE AS ACTIVE_REC_DATE, d2.REG_DATE AS NOTACTIVE_REC_DATE, d1.ACTIVE, d2.ACTIVE FROM [dbo].[test] as d1 
LEFT JOIN CTE d2 ON d2.ATC = d1.ATC AND d2.PID = d1.PID 
AND DATEDIFF(DAY, d2.REG_DATE, d1.REG_DATE) <= 7 
AND d2.ROWNUM = 1 
WHERE d1.ACTIVE=1 AND d1.PID=123456; 

は、クエリがどのように振る舞うべきかとき、最後の7から以前のレコードがありません日が存在する。

+0

この場合、結合された列はnullになります。 – Shift

+0

解決策を探しているうちに、いくつかのテストシナリオを実行したが、rownum 1は必ずしも正しい行ではなかった。 – Shift

関連する問題