2016-09-27 8 views
0

を変更した行の選択、私は以下のフィールドを持つ担当者のテーブルを持っている:TSQL - 列の値が

enter image description here

RepNbrへの変更がある場合もあります。私は、それぞれの効果のためにrepnbrが何であったかを示すクエリを書く必要があります。以前はrepnbrが何をしていたのですか?ですから、私は10/21のM258のrepnbrを取り戻そうとしています(repnbrは以前のものでした)、6/3/16のDM25のrepnbrとM258のrepnbrは6/8/16にありました。

私は次のクエリを試しました:このクエリは6/3と6/8の効果を引き出すだけで、以前のrepnbrの内容を振り返りません。

;with t1 as 
(
select 
    acctnbr, 
    repnbr, 
    effectivedate, 
    rn = row_number() over (partition by repnbr order by acctnbr) 
from 
    reptable 
where 
    acctnbr = '123' 
) 
select 
    * 
from 
    t1 
where 
    rn = '1' 
order by 
    effectivedate 

結果:私は私のクエリで間違って何をやっている

enter image description here

enter image description here

は私の出力は次のようになりますか?あなたが説明するように、あなたの結果はなりませんので、あなたの例では、効力発生日の順序ではないことを おかげで、SQL 2012+のための

+0

方法をすべきをグループ化したバージョンを切断します出力は?のように見える? –

+0

'私は10/21でM258のrepnbrをプルしようとしています - あなたのコードでこれについての参照は見つかりません – techspider

+0

あなたがしたのは、1行のデータを除外したことです。 Acct、EffectiveDateで区切りたいので、有効期限ごとに各アカウントごとに1つのレコードを取得します。とにかくあなたの行はユニークなので、これはすべて簡単です。おそらくあなたの実際のデータセットがより良い例を示すでしょう。 – scsimon

答えて

1

使用LAG()およびまたはLEAD()機能

DECLARE @Rep AS TABLE (Acct INt, RepNbr CHAR(4), EffectiveDate DATETIME) 
INSERT INTO @Rep VALUES 
(123,'M258','2015-10-15') 
,(123,'M258','2015-10-21') 
,(123,'DM25','2015-06-03') 
,(123,'M258','2015-06-08') 

;WITH cte AS (
    SELECT * 
     ,LAG(RepNbr) OVER (PARTITION BY Acct ORDER BY EffectiveDate) as PrevRepNbr 
    FROM 
     @Rep 
) 

SELECT Acct, RepNbr, EffectiveDate 
FROM 
    cte 
WHERE 
    PrevRepNbr IS NULL 
    OR PrevRepNbr <> RepNbr 

注けれども。

:10-21あなたがあなたの例のテーブルを変更した場合はそれがRepNbrのみM258

にDM25から6/8に変更することを意味するので、

Acct RepNbr EffectiveDate 
123  DM25 2015-06-03 00:00:00.000 
123  M258 2015-06-08 00:00:00.000 
123  M258 2015-10-15 00:00:00.000 
123  M258 2015-10-21 00:00:00.000 

... 6-3の後であるため、

DECLARE @Rep AS TABLE (Acct INt, RepNbr CHAR(4), EffectiveDate DATETIME) 
INSERT INTO @Rep VALUES 
(123,'M258','2015-06-03') 
,(123,'M258','2015-06-08') 
,(123,'DM25','2015-10-15') 
,(123,'M258','2015-10-21') 

そして、それは10月15日にDM25に6/3の変化にM258で始まるwoudl、その後、10月21日に戻ってM258に変更します。

あなたは開始/元の値を表示したくない場合は、単に@RepなしWHERE PrevRepNbr IS NULL

編集削除:

;WITH cte AS (
    SELECT 
     Acct 
     ,RepNbr 
     ,EffectiveDate 
     ,LAG(RepNbr) OVER (PARTITION BY Acct ORDER BY EffectiveDate) as PrevRepNbr 
    FROM 
     TableName 
) 

SELECT Acct, RepNbr, EffectiveDate 
FROM 
    cte 
WHERE 
    PrevRepNbr IS NULL 
    OR PrevRepNbr <> RepNbr 
+0

これは、私に600000以上のアカウントが@Repに挿入を行うことを除いて、 INSERT INTOを実行せずにデータをプルする方法はありますか?私は一例を示しているだけです。 – BIReportGuy

+0

ええと@Repを元のテーブルのFROM Tablenameに置き換えて、テーブル変数を全く使わないでください。 – Matt

+0

@BIGuy私の答えがうまく働いていれば、それを受け入れることを考慮してください。ありがとう。 http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work – Matt

1

古いSQLは

DECLARE @Rep AS TABLE (Acctnbr int, RepNbr CHAR(4), EffectiveDate DATETIME) 
INSERT INTO @Rep VALUES 
(123,'M258','2015-10-15') 
,(123,'M258','2015-10-21') 
,(123,'DM25','2015-06-08') 
,(123,'M258','2015-06-03'); 

WITH cte AS (
    select *, 
    grp = row_number() over(partition by acctnbr order by effectivedate) 
    - row_number() over(partition by acctnbr, RepNbr order by effectivedate) 
    from @rep 
) 
SELECT acctnbr, RepNbr, max(effectivedate) effectivedate 
from cte 
group by acctnbr, RepNbr, grp 
order by acctnbr, max(effectivedate) desc; 
+0

変更は通常、有効期限が最長でない場合に有効になりますが、期待通りの結果とサンプルデータが不足しているため、注文。 – Matt

+1

@matt、確実なOPはそれを並べ替えることができ、必要に応じてmin/maxを選択することができます。とにかくヒントをありがとう。 – Serg