1

現在の行の前にある順序付けられたパーティションの部分に、現在の行のフィールドの値が表示される回数をカウントするウィンドウ関数を作成したいと思います。これをより具体的にするために、次のようなテーブルがあるとします。

| id| fruit  | date |
+---+--------+------+
| 1 | apple  |   1  |
| 1 | cherry |   2  |
| 1 | apple  |   3  |
| 1 | cherry |   4  |
| 2 | orange |   1  |
| 2 | grape  |   2  |
| 2 | grape  |   3  |

そして、そのようなテーブルを作成したいと思います(わかりやすくするために日付列を省略しています)。

| id| fruit  | prior |  
+---+--------+-------+
| 1 | apple  |   0   |
| 1 | cherry |   0   |
| 1 | apple  |   1   |
| 1 | cherry |   1   |
| 2 | orange |   0   |
| 2 | grape  |   0   |
| 2 | grape  |   1   |

の場合、順序付けられたパーティションに沿って移動すると、最初のエントリ「apple」は何にも一致しませid = 1ん(暗黙のセットが空であるため)、次のフルーツ「cherry」も一致しません。次に、再び「アップル」に到達します。これは一致などです。SQLは次のようになっていると思います。

SELECT
id, fruit, 
<some kind of INTERSECT?> OVER (PARTITION BY id ORDER by date) AS prior
FROM fruit_table; 

しかし、私は正しく見えるものを見つけることができません。FWIW、PostgreSQL8.4を使用しています。

4

1 に答える 1

3

自己左結合count():を使用して、ウィンドウ関数なしでかなりエレガントにそれを解決できます。

SELECT t.id, t.fruit, t.day, count(t0.*) AS prior
FROM   tbl t
LEFT   JOIN tbl t0 ON (t0.id, t0.fruit) = (t.id, t.fruit) AND t0.day < t.day
GROUP  BY t.id, t.day, t.fruit
ORDER  BY t.id, t.day
  • すべてのSQL標準とPostgreSQLで予約語であるdayため、日付列の名前を変更しました。date

  • サンプルデータの間違いを訂正しました。彼らはあなたがそれを持っていたように、それはチェックアウトしませんでした。人々を混乱させるかもしれません。


あなたのポイントがウィンドウ関数でそれをすることであるならば、これはうまくいくはずです:

SELECT id, fruit, day
      ,count(*) OVER (PARTITION BY id, fruit ORDER BY day) - 1 AS prior
FROM   tbl
ORDER  BY id, day

frame_endを省略すると、デフォルトでCURRENTROWになります。

  • (id, fruit)現在の行を含め、前日に同じ行がいくつあったかを効果的に数えます。それ- 1が目的です。
于 2012-02-20T21:51:27.870 に答える