0

既存の @table があります

ID  Date    Val
1   2014-10-01  1
2   2014-10-02  1
3   2014-10-03  1
4   2014-10-04  1
5   2014-10-05  1
6   2014-10-06  1
7   2014-10-07  1
8   2014-10-08  1
9   2014-10-09  1

日付順は重要です。各 Val シーケンスの最初と最後の日付を確認する必要があります。

Select Val,MIN([Date]) as A, MAX([Date]) as B
        from @T
        Group by Val

   Val  From        To
    1   2014-10-01  2014-10-09

Val 列は、次の 3 つのエントリで変更されます。

Update @T set Val = 2 where [ID] between 3 and 5

そして戻ります:

ID  Date    Val
1   2014-10-01  1
2   2014-10-02  1
3   2014-10-03  2
4   2014-10-04  2
5   2014-10-05  2
6   2014-10-06  1
7   2014-10-07  1
8   2014-10-08  1
9   2014-10-09  1

シーケンスごとに最小/最大の日付を返すように SQL を取得するにはどうすればよいですか? 私は示す必要があります:
すなわち

1   2014-10-01  2014-10-02
2   2014-10-03  2014-10-05
1   2014-10-06  2014-10-09

通常の Min/Max クエリを実行すると、

1   2014-10-01  2014-10-09
2   2014-10-03  2014-10-05

これは、val が第 1 ピリオドで 1、第 2 ピリオドで 2、第 3 ピリオドで再び 1 であることを示していません。

declare @T table(ID int,[Date] date,Val int)
Insert Into @T(ID,[Date],Val)
 values(1,'2014/10/01', 1),
(2,'2014/10/02',    1),
(3,'2014/10/03',    1),
(4,'2014/10/04',    1),
(5,'2014/10/05',    1),
(6,'2014/10/06',    1),
(7,'2014/10/07',    1),
(8,'2014/10/08',    1),
(9,'2014/10/09',    1)
4

1 に答える 1

1

これを試して

SELECT Val,Min(Date) Min_Date,Max(Date) Max_Date 
FROM
(
SELECT ID,Date,Val,SUM(NewVal) OVER (order by ID) AS NewVal
FROM
    (
    SELECT ID,Date,Val,CASE WHEN Val<>LAG(Val, 1) OVER (ORDER BY ID) THEN 1 ELSE 0 END NewVal
    FROM @T
    ) I
) O
GROUP BY NewVal,Val
ORDER BY Min_Date

私は自分の質問の1つに対する以前の回答から回答を採用しましたhttps://stackoverflow.com/a/21635529/1181412

基本的に、前の行の値を比較するために LAG 関数を使用しています。異なる場合は 1 にし、それ以外の場合は 0 を使用します。次に、NewVal が 1 上がるたびに増加する実行中の合計でそれをラップします。クエリの結果は、探しているものと一致します。

レコードの順序は、この回答にとって明らかに非常に重要です。そのため、特定のニーズに応じて、OVER 句を調整する必要がある場合があります。

編集

コメントによると、これは LAG を使用しない代替の回答であるため、SQL Server 2008 で動作します。

SELECT Val,Min(Date) Min_Date,Max(Date) Max_Date 
FROM
(
SELECT ID,Date,Val,SUM(NewVal) OVER (order by ID) AS NewVal
FROM
    (
    SELECT M.ID,M.Date,M.Val,CASE WHEN M.Val<>L.Val THEN 1 ELSE 0 END NewVal
    FROM @T M
    LEFT JOIN
        (
        SELECT ID,Date,Val,ROW_NUMBER() OVER(order by ID)+1 NewRowId
        FROM @T
        ) L ON M.ID=L.NewRowId
    ) I
) O
GROUP BY NewVal,Val
ORDER BY Min_Date
于 2015-04-09T14:47:47.683 に答える