2016-05-26 2 views
3

異なる製品の起動の間に経過した日数を割り当てる必要があります。これは私が持っているデータの一例である:T-SQL製品の起動中に実行中の稼働日数を割り当てると、製品の起動時に0にリセットされます。

SELECT TiD 
     , Launch 
     , COUNT(1) OVER(PARTITION BY Launch ORDER BY TiD) DaysSinceLastLaunch 
FROM #TestingData 
ORDER BY TiD ASC 

は、しかし、それはカウントをゼロにリセットしません:

SELECT '2016-01-01' TiD, 1 Launch, NULL DaysBetween 
INTO #TestingData 
UNION 
SELECT '2016-01-02', 0, NULL DaysBetween 
UNION 
SELECT '2016-01-03', 0, NULL DaysBetween 
UNION 
SELECT '2016-01-04', 1, NULL DaysBetween 
UNION 
SELECT '2016-01-05', 0, NULL DaysBetween; 

が、私はこのクエリを使用しようとしました。最終結果が次のように必要な場合:

SELECT '2016-01-01' TiD, 1 Launch, 0 DaysBetween 
INTO #CorrectData 
UNION 
SELECT '2016-01-02', 0, 1 DaysBetween 
UNION 
SELECT '2016-01-03', 0, 2 DaysBetween 
UNION 
SELECT '2016-01-04', 1, 0 DaysBetween 
UNION 
SELECT '2016-01-05', 0, 1 DaysBetween; 

何をする必要がありますか?カーソルを使うべきですか?

おかげ

+2

あなたが発射されたプロジェクトの関連したIDまたは名前を持っている場合は、その値に分割窓関数がうまく動作します。 – dfundako

+1

Googleの「SQLギャップと諸島の問題」の例がたくさんあります。 –

答えて

1

を知ってみましょう。この回答と他の回答の違いは、Launch = 1とは対照的に、TOP 1がCTEの最初の部分にあり、複数の行が返される可能性があります。 (正直なところ私は他の答えをテストしていない)。

注:注:これは、あなたのサンプルデータがあなたにしていると連続していることを前提としています。

SELECT '2016-01-01' TiD, 1 Launch, NULL DaysBetween 
INTO #TestingData 
UNION 
SELECT '2016-01-02', 0, NULL DaysBetween 
UNION 
SELECT '2016-01-03', 0, NULL DaysBetween 
UNION 
SELECT '2016-01-04', 1, NULL DaysBetween 
UNION 
SELECT '2016-01-05', 0, NULL DaysBetween 

;WITH cte 
      AS (SELECT TOP 1 
         TiD , 
         Launch , 
         0 AS DaysBetween 
       FROM  #TestingData 
       ORDER BY TiD 
       UNION ALL 
       SELECT t1.TiD , 
         t1.Launch , 
         CASE WHEN t1.Launch = 1 THEN 0 
          ELSE cte.DaysBetween + 1 
         END AS Launch 
       FROM  #TestingData t1 
         INNER JOIN cte ON t1.TiD = DATEADD(DAY, 1, cte.TiD) 
      ) 
    SELECT * 
    FROM cte 

DROP TABLE #TestingData 

出力:

TiD   Launch DaysBetween 
2016-01-01 1  0 
2016-01-02 0  1 
2016-01-03 0  2 
2016-01-04 1  0 
2016-01-05 0  1 
1
WITH REC_CTE (tid,launch,Daysbetween) 
    AS (
     -- Anchor definition 
     SELECT tid, 
       launch, 
       0 as Daysbetween 
     FROM #tmp 
     WHERE launch = 1 
     -- Recursive definition 
     UNION ALL 
     SELECT son.tid, 
       son.launch, 
       father.Daysbetween + 1 
     FROM #tmp son INNER JOIN 
      REC_CTE father 
     on son.tid = dateadd(dd,1,father.tid) 
     WHERE son.launch = 0 
    ) 

SELECT * from REC_CTE order by tid asc 

あなたはあなたのために仕事をする再帰CTEを使用することができます。すべての反復で、最後の打ち上げから毎日+1します。

は、私はあなたが働いてそれを得るカント場合sqlfiddleを提供することができ、ちょうど私が仕事をして迅速なCTEをここで

+0

あなたは完璧に仕事をしてくれてありがとう! – Dan

関連する問題