4. Lag関数の引数に行コンストラクタ
最後は、Lag
関数の引数に行コンストラクタを使うSQLです。『PostgreSQLの分析関数の衝撃6』で、『4.2.12. 行コンストラクタ』を少し紹介しましたが、今度はLag
関数の引数に行コンストラクタを使ってみます。サンプルを見てみましょう。
SortKey | Val1 | Val2 |
10 | 1 | 5 |
12 | 3 | 7 |
14 | 3 | 7 |
15 | 1 | 5 |
19 | 3 | 7 |
25 | 3 | 5 |
30 | 3 | 5 |
SortKeyの昇順で、前の行とVal1が等しく、かつ前の行とVal2が等しいかをチェックした結果を列別名PrevIsSame
として表示します。
SortKey | Val1 | Val2 | PrevIsSame |
10 | 1 | 5 | 0 |
12 | 3 | 7 | 0 |
14 | 3 | 7 | 1 |
15 | 1 | 5 | 0 |
19 | 3 | 7 | 0 |
25 | 3 | 5 | 0 |
30 | 3 | 5 | 1 |
case
式とLag
関数を組み合わせて、答えは下記となります。
select SortKey,Val1,Val2, case when Val1 = Lag(Val1) over(order by SortKey) and Val2 = Lag(Val2) over(order by SortKey) then 1 else 0 end as PrevIsSame from LagTest;
SQLのイメージは下記となります。Lag(Val1) over(order by SortKey)
に対応する黄緑線と、Lag(Val2) over(order by SortKey)
に対応する青線を引いてます。
Lag
関数を2回ではなく、1回で済ませたいと思ったら、下記の行コンストラクタを使用したSQLの出番です。行コンストラクタは『C#の匿名型』と似たようなものと考えると分かりやすいかもしれません。
select SortKey,Val1,Val2, case when Row(Val1,Val2) = Lag(Row(Val1,Val2)) over(order by SortKey) then 1 else 0 end as PrevIsSame from LagTest;
SQLのイメージは下記となります。Lag(Row(Val1,Val2)) over(order by SortKey)
に対応する黄緑線を引いてます。
このように行間比較する列が複数の場合は、行コンストラクタを使用するとSQLがシンプルになることがあります。
最後に
本稿では、window
関数の変わった使用例を扱いました。次回は、OracleやDB2の分析関数のRows
指定とRange
指定をPostgreSQL 8.4で代用する方法を扱います。
参考資料
- 9.19. ウィンドウ関数
PostgreSQLのマニュアルです。ウィンドウ関数に関する説明です。