MySQLで、Oracleの分析関数と同じ結果を取得する4
山岸賢治 [著] 2008/12/18 14:00
このエントリーをはてなブックマークに追加

SourceCode 3.60 KB
1 2 3 4 5 →

 連載「分析関数の衝撃」では、Oracleの分析関数を主に扱いました。「分析関数の衝撃」の外伝となるこの連載では、 MySQLで、Oracleの分析関数と同じ結果を取得するSQLの考え方と、処理のイメージを解説します。今回は、Range指定およびRows指定のSum関数と同じ結果を取得するSQLを扱います。

はじめに

 本稿では、Oracleの分析関数の中で、Range指定およびRows指定のSum関数と同じ結果を取得するSQLを扱います。

対象読者

  • MySQLやPostgreSQLで、分析関数と同じ結果を取得するSQLを書きたい方
  • OracleやDB2やSQL Serverの、分析関数の理解を深めたい方

必要な環境

 本稿で扱うSQLは、MySQL 5.1.28で動作確認しました。ソースコードはPostgreSQL 8.3とOracle 10.2.0.1.0でも動作確認しました。その他、次の環境でも応用が可能です。

  • SQL Server
  • DB2

1. Range指定のSum関数

 最初は、Range指定のSum関数と同じ結果を求めるSQLについてです。まずは、テーブルのデータと、出力結果を考えます。

IDTable
IDSeqVal
AA1100
AA2100
AA3500
AA4200
AA5200
AA650
BB1200
BB2400
BB3800
BB4900
CC1100
CC2800
CC3700
DD1400
EE150
FF110
FF320
FF540
FF680

 同じIDで、Seqが自分より1小さい行から2大きい行までのValの合計を求めます。言いかえれば、Oracleの下記の分析関数を使ったSQLと同じ結果を取得します。

分析関数を使ったSQL
select ID,Seq,Val,
sum(Val) over(partition by ID order by Seq
              range between 1 preceding
                        and 2 following) as sumVal
  from IDTable
order by ID,Seq;
出力結果
IDSeqValsumVal
AA1100700 (100+100+500)
AA2100900 (100+100+500+200)
AA35001000 (100+500+200+200)
AA4200950 (500+200+200+50)
AA5200450 (200+200+50)
AA650250 (200+50)
BB12001400 (200+400+800)
BB24002300 (200+400+800+900)
BB38002100 (400+800+900)
BB49001700 (800+900)
CC11001600 (100+800+700)
CC28001600 (100+800+700)
CC37001500 (800+700)
DD1400400
EE15050
FF11030 (10+20)
FF32060 (20+40)
FF540120 (40+80)
FF680120

 相関サブクエリでの、Range指定の分析関数の代用は簡単で、下記が答えとなります。

相関サブクエリを使うSQL
select ID,Seq,Val,
(select sum(b.Val)
   from IDTable b
  where b.ID = a.ID
    and b.Seq between a.Seq-1 and a.Seq+2) as sumVal
  from IDTable a
order by ID,Seq;

 相関サブクエリのbetween述語で、「IDが同じであること」および「Seqが自分より1小さい値以上、かつ、自分より2大きい値以下であること」を条件とし、Sum関数でValの合計を求めています。SQLのイメージは下記です。

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

こちらの関連記事もおすすめです

プロフィール
山岸賢治 ヤマギシケンジ

Oracle ACEの1人。
OracleSQLパズルの運営者。
ORACLE MASTER Silver Oracle Database 10g
(研修受講で)ORACLE MASTER Gold Oracle Database 10g
ソフトウェア開発技術者 (情報処理技術者試験)
第二種情報処理技術者 (情報処理技術者試験)
 


記事へのコメント・トラックバック機能は2011年6月に廃止させていただきました。記事に対する反響はTwitterやFacebook、ソーシャルブックマークサービスのコメントなどでぜひお寄せください。

スポンサーサイト