2017-02-13 8 views
1

以下のデータセットがあります。これから、PersonIDのステータスが以前のステータスとは異なるステータスに変更された各グループから、最初の行を選択したいとします。LAG機能を使用せずにこのデータをグループ化するには

たとえば、このデータセットからは、1,4,7、および11の行が必要です。 これに関する助言はありますか。 私がGROUPBYを実行すると、それはすべての新規グループとすべての2つのグループの保留グループをまとめているだけです。私はSQL Server 2008しか持っていないので、ラグ機能は動作しません。

PersonID Status WhenChanged 
101   New  27/01/2017 15:27 
101   New  27/01/2017 16:40 
101   New  27/01/2017 16:40 
101   Pending 27/01/2017 16:40 
101   Pending 27/01/2017 16:40 
101   Pending 27/01/2017 16:40 
101   New  31/01/2017 09:14 
101   New  31/01/2017 10:02 
101   New  31/01/2017 10:03 
101   New  31/01/2017 10:05 
101   Pending 03/02/2017 14:29 
101   Pending 03/02/2017 14:29 
+0

あなたの 'WhenChanged'は真剣に' VARCHAR'値ですか? – Siyual

+1

あなたの構造では、これは不可能です。あなたのdatetime値( 'VARCHAR'のような疑わしいもの)は一意ではありません。ソートするものは何もありません。これらの結果を注文するものがなければ、結果の保証された順序はありません。したがって、あなたが望む結果を得ることが不可能になります。レコードの一意のIDが必要です。 – Siyual

答えて

4

あなたはrow_numbers()の違いでこれを行うと、別のrow_number()ことができます。

select PersonID, Status, WhenChanged 
from (select t.*, 
      row_number() over (partition by personid, status, seqnum_p - seqnum_ps 
           order by whenchanged 
           ) as seqnum 
     from (select t.*, 
        row_number() over (partition by personid order by whenchanged) as seqnum_p, 
        row_number() over (partition by personid, status order by whenchanged) as seqnum_ps 
      from t 
      ) t 
    ) t 
where seqnum = 1; 

これがどのように機能するかを理解するために、私はあなたがサブクエリを実行し、結果を見ていることを示唆しています。これらの行番号の違いによってグループが定義されます。

代替方法はouter applyです。しかし、上記の方がパフォーマンスが良いでしょう。

+0

多くのありがとうゴードン、これは完璧に動作します:-) – Tan

関連する問題