SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

分析関数の衝撃

PostgreSQLの分析関数の衝撃(7)
――window関数の変わった使用例

order by句でのwindow関数など

  • X ポスト
  • このエントリーをはてなブックマークに追加

ダウンロード SourceCode (1.3 KB)

3. Oracleのkeep指定を模倣

 次は、Oracleのkeep指定を模倣するSQLです。サンプルを見てみましょう。

KeepDense
ID SortKey1 SortKey2 Val
111 1 5 10
111 2 3 20
111 3 1 60
111 3 1 100
222 1 2 200
222 1 3 300
222 2 4 400
222 2 4 500
333 1 2 600
333 1 3 100

 OracleのSQLで使用できる分析関数でのkeep指定を模倣してみます。

模倣対象のOracleのSQL(分析関数でのkeep指定)
select ID,SortKey1,SortKey2,Val,
sum(Val) over(partition by ID) as SumVal1,
sum(Val) Keep(Dense_Rank Last order by SortKey1,SortKey2)
over(partition by ID) as SumVal2
  from KeepDense
order by ID,SortKey1,SortKey2,Val;

 答えは、Keep(Dense_Rank Last order by SortKey1,SortKey2)order by SortKey1,SortKey2の逆ソート(ascdescを入れ替えたソート)である、order by SortKey1 desc,SortKey2 descを使ったdense_rank関数の結果を、case式でwindow関数の集計対象かを判定するのに使用した下記のSQLとなります。

 なお、array_agg関数は、sum関数の加算元をデバッグ用に表示したい時などに便利なので、例として使用してます。

case式でwindow関数の集計対象かを判定
select ID,SortKey1,SortKey2,Val,
sum(Val) over(partition by ID) as SumVal1,
sum(case rn when 1 then Val end)
over(partition by ID) as SumVal2,
array_agg(case rn when 1 then Val end)
over(partition by ID) as BaseOfSumVal2
from (select ID,SortKey1,SortKey2,Val,
      dense_rank()
      over(partition by ID
           order by SortKey1 desc,SortKey2 desc) as rn
      from KeepDense) a
order by ID,SortKey1,SortKey2,Val;
出力結果
ID SortKey1 SortKey2 Val SumVal1 SumVal2 BaseOfSumVal2
111 1 5 10 190 160 {60,100,NULL,NULL}
111 2 3 20 190 160 {60,100,NULL,NULL}
111 3 1 60 190 160 {60,100,NULL,NULL}
111 3 1 100 190 160 {60,100,NULL,NULL}
222 1 2 200 1400 900 {400,500,NULL,NULL}
222 1 3 300 1400 900 {400,500,NULL,NULL}
222 2 4 400 1400 900 {400,500,NULL,NULL}
222 2 4 500 1400 900 {400,500,NULL,NULL}
333 1 2 600 700 100 {100,NULL}
333 1 3 100 700 100 {100,NULL}

 SQLのイメージは下記となります。partition by IDに対応する赤線を引いてます。

SQLのイメージ
SQLのイメージ

集約関数でのkeep指定を模倣

 次は、OracleのSQLで使用できる集約関数でのkeep指定を模倣してみます。

模倣対象のOracleのSQL(集約関数でのkeep指定)
select ID,sum(Val) as SumVal1,
sum(Val) Keep(Dense_Rank Last order by SortKey1,SortKey2)
as SumVal2
  from KeepDense
group by ID
order by ID;

 同じような考え方を使って、答えは下記となります。array_agg関数は、sum関数の加算元をデバッグ用に表示したい時などに便利なので、例として使用してます。

case式で集約関数の集計対象かを判定
select ID,sum(Val) as SumVal1,
sum(case rn when 1 then Val end) as SumVal2,
array_agg(case rn when 1 then Val end) as BaseOfSumVal2
from (select ID,SortKey1,SortKey2,Val,
      dense_rank()
      over(partition by ID
           order by SortKey1 desc,SortKey2 desc) as rn
      from KeepDense) a
group by ID
order by ID;
出力結果
ID SortKey1 SortKey2 BaseOfSumVal2
111 190 160 {60,100,NULL,NULL}
222 1400 900 {400,500,NULL,NULL}
333 700 100 {100,NULL}

次のページ
4. Lag関数の引数に行コンストラクタ

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
分析関数の衝撃連載記事一覧

もっと読む

この記事の著者

山岸 賢治(ヤマギシ ケンジ)

趣味が競技プログラミングなWebエンジニアで、OracleSQLパズルの運営者。AtCoderの最高レーティングは1204(水色)。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/4790 2010/02/15 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング