2012-03-21 13 views
1

従業員ステータスと有効日のテーブルがある場合、のステータスを反映するデータだけをで取得できますか?データの実際の重要な変更を反映するクエリ

は、例えば、以下の構造を与えられた:

DECLARE @STATUSES TABLE(
    EMPLOYEE_ID INT NOT NULL, 
    EFFECTIVE_DATE DATE NOT NULL, 
    STATUS_CODE CHAR(1) NOT NULL 
) 
INSERT @STATUSES VALUES (1, '2012-01-01', 'A') 
INSERT @STATUSES VALUES (1, '2012-02-28', 'A') 
INSERT @STATUSES VALUES (1, '2012-03-01', 'T') 
INSERT @STATUSES VALUES (2, '2012-01-01', 'A') 
INSERT @STATUSES VALUES (2, '2012-02-14', 'A') 
INSERT @STATUSES VALUES (2, '2012-03-10', 'A') 
INSERT @STATUSES VALUES (3, '2012-02-01', 'A') 
INSERT @STATUSES VALUES (3, '2012-03-17', 'A') 
INSERT @STATUSES VALUES (3, '2012-03-18', 'T') 
INSERT @STATUSES VALUES (3, '2012-04-01', 'A') 
INSERT @STATUSES VALUES (4, '2012-03-01', 'A') 

何問合せは、下記をもたらすために使用することができますか?言い換えれば

EMPLOYEE_ID  EFFECTIVE_DATE  STATUS_CODE 
1    2012-01-01   A 
1    2012-03-01   T 
2    2012-01-01   A 
3    2012-02-01   A 
3    2012-03-18   T 
3    2012-04-01   A 
4    2012-03-01   A 

、私は1つが、以前の有効日付で存在する場合、その前のものと同じ従業員IDとステータスコードを持って、それらのレコードを残したいです。ステータスが実際に変更されたのは2つだけだったので、従業員1は2回のみ表示されています。ステータスは以前の日付から変更されていないため、2012-02-28のステータスは重要ではありません。また、従業員2は、3つのレコードがあるにもかかわらず、ステータスが変更されていないので、ただ1回リストされています。各変更に対して最も早い日付のみが表示されます。

答えて

1

さらに実験すると、これは私が望むことをするように見えます。

;WITH cte 
    AS (SELECT ROW_NUMBER() OVER (PARTITION BY EMPLOYEE_ID ORDER BY EFFECTIVE_DATE) AS rownum 
       ,EMPLOYEE_ID 
       ,EFFECTIVE_DATE 
       ,STATUS_CODE 
     FROM @STATUSES) 
SELECT t2.EMPLOYEE_ID 
     ,t2.EFFECTIVE_DATE 
     ,t2.STATUS_CODE 
FROM cte t2 
     LEFT JOIN cte t1 
     ON t2.EMPLOYEE_ID = t1.EMPLOYEE_ID 
      AND t2.STATUS_CODE = t1.STATUS_CODE 
      AND t2.rownum = t1.rownum + 1 
WHERE t1.EMPLOYEE_ID IS NULL 
+1

また、 'ON'節に' AND t2.STATUS_CODE = t1.STATUS_CODE'を追加し、 'WHERE t1.EMPLOYEE_ID IS NULL'のようなものに' WHERE'節を変更することもできます。 –

+0

@AndriyM良い点、私は良い、おかげで読む方法が好きです。更新しました。 – JustinStolle

0
SELECT 
    EMPLOYEE_ID, MIN(EFFECTIVE_DATE) AS EFFECTIVE_DATE, STATUS_CODE 
FROM 
    (
    SELECT 
     T1.EMPLOYEE_ID, T1.EFFECTIVE_DATE, T1.STATUS_CODE, 
     MAX(T2.EFFECTIVE_DATE) AS MOST_RECENT_PREVIOUS_STATUS_DATE 
    FROM 
     @STATUSES T1 
     LEFT JOIN 
     @STATUSES T2 
     ON 
     T1.EMPLOYEE_ID = T2.EMPLOYEE_ID 
      AND 
     T1.EFFECTIVE_DATE > T2.EFFECTIVE_DATE 
      AND 
     T1.STATUS_CODE <> T2.STATUS_CODE 
    GROUP BY 
     T1.EMPLOYEE_ID, T1.EFFECTIVE_DATE, T1.STATUS_CODE 
    ) SubQuery 
GROUP BY 
    EMPLOYEE_ID, STATUS_CODE, MOST_RECENT_PREVIOUS_STATUS_DATE 
+0

CTE方法は、より効率的であった場合、私は興味があると思い@PreviousRecord変数

にCurrentRecord値は知っています。 – JustinStolle

0

あなたは変数の二組が必要と思い

CURSOR使用することができます

取得@PreviousRecordと@CurrentRecord

社員と日付でソートされたテーブルのカーソルを宣言し@PreviousRecord変数にカーソルからの最初のレコード - あなたの要件に応じてこれを重要な変更として登録するか(一時テーブルにレコードを書き込む)


は、前のレコードと比較@CurrentRecord変数に次のレコードを取得し、それが大きな変化のためのあなたの条件に一致した場合
が移動し、一時テーブルに書き込む@:

は、そのループを設定しますこれは、同様に動作

関連する問題