2

私はいくつかの記録を持っています:

+---+--------+---------------------------+
| | | | データ | データ 時間 |
+---+--------+---------------------------+
| | 1 | 1 | 2013-04-22 16:18:07 |
| | 2 | 1 | 2013-04-22 16:18:17 |
| | 3 | 2 | 2013-04-22 16:18:27 |
| | 4 | 2 | 2013-04-22 16:18:37 |
| | 5 | 1 | 2013-04-22 16:18:47 |
| | 6 | 1 | 2013-04-22 16:18:57 |
| | 7 | 1 | 2013-04-22 16:19:07 |
| | 8 | 3 | 2013-04-22 16:19:17 |
| | 9 | 3 | 2013-04-22 16:19:27 |
| | 10| 1 | 2013-04-22 16:19:37 |
| | 11| 2 | 2013-04-22 16:19:47 |
| | 12| 2 | 2013-04-22 16:19:57 |
| | 13| 3 | 2013-04-22 16:20:07 |
| | 14| 3 | 2013-04-22 16:20:17 |
+---+--------+---------------------------+

これらのレコードを取得するにはどうすればよいですか?:

+---+--------+---------------------------+
| | | | データ | データ 時間 |
+---+--------+---------------------------+
| | 1 | 1 | 2013-04-22 16:18:07 |
| | 3 | 2 | 2013-04-22 16:18:27 |
| | 5 | 1 | 2013-04-22 16:18:47 |
| | 8 | 3 | 2013-04-22 16:19:17 |
| | 10| 1 | 2013-04-22 16:19:37 |
| | 11| 2 | 2013-04-22 16:19:47 |
| | 13| 3 | 2013-04-22 16:20:07 |
+---+--------+---------------------------+

各サブグループの最初のエントリを選択したいのですが、distinct を使用すると、次のレコードの配列があります。

+---+--------+---------------------------+
| | | | データ | データ 時間 |
+---+--------+---------------------------+
| | 1 | 1 | 2013-04-22 16:18:07 |
| | 3 | 2 | 2013-04-22 16:18:27 |
| | 8 | 3 | 2013-04-22 16:19:17 |
+---+--------+---------------------------+
4

3 に答える 3

2

ここでの問題は、見ているグループを定義する必要があることです。「データ」値は、異なるグループに対して繰り返されます。

各グループの検索方法は次のとおりです。時間順に並べられた各行に順次値を割り当てます。次に、各データ値に別の連続した値を時間順に割り当てます。値が連続している場合、これらの値の差は一定です。

以下では、このアイデアをデータに使用しています。グループが識別されると、このメソッドを使用group byしてデータを取得します。

select MIN(data) as data, MIN(time) as time
from (select t.*,
             (ROW_NUMBER() over (order by time) -
              ROW_NUMBER() over (partition by data order by time
             ) as thegroup
      from t
     ) t
group by thegroup

保持したい列がさらにある場合は、各グループの行を列挙して最初の行を取得できます。

select data, time
from (select t.*, ROW_NUMBER() over (partition by thegroup order by time) as seqnum
      from (select t.*,
                   (ROW_NUMBER() over (order by time) -
                    ROW_NUMBER() over (partition by data order by time
                   ) as thegroup
            from t
           ) t
      group by thegroup
     ) t
where seqnum = 1

Postgres のdistinct on構文を使用してこれを行うこともできます。

于 2013-04-22T17:43:10.837 に答える