3

週の範囲内で負の値を持つ連続した 2 週間以上の期間の数をカウントしたいと考えています。

例:

Week | Value
201301 | 10
201302 | -5 <--| both weeks have negative values and are consecutive
201303 | -6 <--| 

 Week | Value
201301 | 10
201302 | -5 
201303 | 7
201304 | -2 <-- negative but not consecutive to the last negative value in 201302 

 Week | Value
201301 | 10
201302 | -5 
201303 | -7
201304 | -2 <-- 1st group of negative and consecutive values 
201305 | 0
201306 | -12
201307 | -8 <-- 2nd group of negative and consecutive values 

カーソルとリセット変数を使用して各行を順番にチェックする以外に、これを行うより良い方法はありますか?

これを試してテストするためにセットアップしたSQLの一部を次に示します。

IF OBJECT_ID('TempDB..#ConsecutiveNegativeWeekTestOne') IS NOT NULL DROP TABLE #ConsecutiveNegativeWeekTestOne
IF OBJECT_ID('TempDB..#ConsecutiveNegativeWeekTestTwo') IS NOT NULL DROP TABLE #ConsecutiveNegativeWeekTestTwo

CREATE TABLE #ConsecutiveNegativeWeekTestOne
(
     [Week] INT NOT NULL
     ,[Value] DECIMAL(18,6) NOT NULL
)

-- I have a condition where I expect to see at least 2 consecutive weeks with negative values
-- TRUE : Week 201328 & 201329 are both negative.
INSERT INTO #ConsecutiveNegativeWeekTestOne
VALUES
(201327, 5)
,(201328,-11)
,(201329,-18)
,(201330, 25)
,(201331, 30)
,(201332, -36)
,(201333, 43)
,(201334, 50)
,(201335, 59)
,(201336, 0)
,(201337, 0)

SELECT * FROM #ConsecutiveNegativeWeekTestOne
WHERE Value < 0
ORDER BY [Week] ASC


CREATE TABLE #ConsecutiveNegativeWeekTestTwo
(
     [Week] INT NOT NULL
     ,[Value] DECIMAL(18,6) NOT NULL
)

-- FALSE: The negative weeks are not consecutive
INSERT INTO #ConsecutiveNegativeWeekTestTwo
VALUES

(201327, 5)
,(201328,-11)
,(201329,20)
,(201330, -25)
,(201331, 30)
,(201332, -36)
,(201333, 43)
,(201334, 50)
,(201335, -15)
,(201336, 0)
,(201337, 0)

SELECT * FROM #ConsecutiveNegativeWeekTestTwo
WHERE Value < 0
ORDER BY [Week] ASC

私の SQL フィドルもここにあります: http://sqlfiddle.com/#!3/ef54f/2

4

3 に答える 3

1

EXISTS の組み合わせを使用できます。

グループのみを知りたいと仮定します(一連の連続した週はすべて負です)

-- 潜在的な開始週を見つける

;WITH starts as (
    SELECT [Week]
    FROM #ConsecutiveNegativeWeekTestOne AS s
    WHERE s.[Value] < 0
      AND NOT EXISTS (
        SELECT 1
        FROM #ConsecutiveNegativeWeekTestOne AS p
        WHERE p.[Week] = s.[Week] - 1
          AND p.[Value] < 0
        )
    )
SELECT COUNT(*)
FROM
    Starts AS s
    WHERE EXISTS (
        SELECT 1
        FROM #ConsecutiveNegativeWeekTestOne AS n
        WHERE n.[Week] = s.[Week] + 1
          AND n.[Value] < 0
        )

週にインデックスがある場合、このクエリは適度に効率的です。

于 2013-06-13T21:33:58.267 に答える