MW211 EXIT

devlog
Oracle/一つ前のレコード
2018年02月02日
一つ前のレコードを参照するには、LAG()関数を使う。こんな感じ。
┌──────────────────────────────────────┐
│SELECT LAG("列") OVER(PARTITION BY "グループ列"                             │
│                      ORDER BY     "ソート列"   ASC) AS "列"                │
│    FROM "表";                                                              │
└──────────────────────────────────────┘
その列だけ局地的に一つ前のレコードを取得するような感じになる。
なお、一つまえのレコードがない場合には、「NULL」になる。

では、結合した場合はどうか?
┌──────────────────────────────────────┐
│SELECT LAG("副表"."列") OVER(PARTITION BY "副表"."グループ列"               │
│                             ORDER BY     "副表"."ソート列"   ASC) AS "列"  │
│    FROM "主表"                                                             │
│        LEFT JOIN "副表"                                                    │
│          ON "副表"."主キー" = "主表"."外部キー";                           │
└──────────────────────────────────────┘
うっかりこういうのはNG。予期せぬ「NULL」が多発する。
なぜなら、LAG()関数はあくまで直前の母集団の一つ前のレコードを探し出してくるので
この場合、"副表"側全部の中の一つ前のレコードとはならないのだ。

とはいえ、以下のようなのはNG。
┌──────────────────────────────────────┐
│SELECT "副表"."列"                                                          │
│    FROM "主表"                                                             │
│        LEFT JOIN "副表" "中継副表"                                         │
│            LEFT JOIN "副表"                                                │
│              ON "副表"."主キー"                                            │
│       = LAG("中継副表"."主キー") OVER(PARTITION BY "副表"."グループ列"     │
│                                       ORDER BY     "副表"."ソート列"   ASC)│
│          ON "中継副表"."主キー" = "主表"."外部キー";                       │
└──────────────────────────────────────┘
「ORA-30483: ここでウィンドウ・ファンクションは使用できません。」エラーとなる。

なので、副問合せの時点で解決してしまうのがよいようだ。
┌──────────────────────────────────────┐
│SELECT "副表"."列"                                                          │
│    FROM "主表"                                                             │
│        LEFT JOIN (                                                         │
│            SELECT "主キー",                                                │
│                   LAG("列") OVER(PARTITION BY "グループ列"                 │
│                                  ORDER BY     "ソート列"   ASC) AS "列"    │
│                FROM "副表"                                                 │
│        ) "副表"                                                            │
│          ON "副表"."主キー" = "主表"."外部キー";                           │
└──────────────────────────────────────┘
本当にこれがベストなのかは不安だが。
分類:Oracle