SHOEISHA iD

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

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

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

分析関数の衝撃

分析関数の衝撃6(応用編)

CodeZineに掲載されたSQLを分析関数で記述する 6

ダウンロード SourceCode (3.0 KB)

3. 次の入社日を求める

 続いて、次の入社日を求めるSQLです。まずは、テーブルのデータと、出力結果を考えます。

入社テーブル
名前 入社日
Scott 2000-12-23
Tiger 2001-10-12
Kim 2003-04-01
Tom 2003-04-01
Wendy 2003-04-01
Joe 2003-04-01
John 2004-05-30
Hideyoshi 2004-07-30
Ieyasu 2004-07-30
Nobunaga 2004-07-30
Mithuhide 2005-12-30

 それぞれの、次に入社した人の入社日を求めます。例えば、Scottの次に入社した人はTigerでその入社日は2001-10-12。Tigerの次に入社した人はKimでその入社日は2003-04-01。Kimの次に入社した人はJohnでその入社日は2004-05-30。となります。

出力結果
名前 入社日 次の入社日
Scott 2000-12-23 2001-10-12
Tiger 2001-10-12 2003-04-01
Kim 2003-04-01 2004-05-30
Tom 2003-04-01 2004-05-30
Wendy 2003-04-01 2004-05-30
Joe 2003-04-01 2004-05-30
John 2004-05-30 2004-07-30
Hideyoshi 2004-07-30 2005-12-30
Ieyasu 2004-07-30 2005-12-30
Nobunaga 2004-07-30 2005-12-30
Mithuhide 2005-12-30 null

 この問題のポイントは、どのようにして分析関数で行間アクセスを行うかです。もし、入社日に重複がないなら、単純に下記のようにLead関数を使えばよいです。

select 名前,入社日,
Lead(入社日) over(order by 入社日) as 次の入社日
  from 入社

 しかし、上記のようにLead関数を使っても、入社日に重複があるので正しい結果を得ることはできません。 Lead関数とLag関数は、ソートキーによって行が一意にならない場合は、ほとんど使い道がないのです。

 次の入社日は、自分より大きい入社日の中で最小の入社日だと考えて、答えは下記となります。

答え
select 名前,入社日,
min(入社日) over(
order by 入社日
range between 1 following
          and unbounded following) as 次の入社日
  from 入社
order by 入社日,名前;

 range指定のmin関数を使って、自分より大きい入社日の中で最小の入社日(最小上界)を求めてます。以下のように解釈すると分かりやすいでしょう。

min(入社日) over(  --以下の範囲で最小の入社日を求める。
order by 入社日    --入社日の昇順で、
range between      --行の範囲は、
      1 following  --小さいほうは、1日後から
  and unbounded following) --大きいほうは際限なし

 SQLのイメージは下記となります。

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

次のページ
4. case式とignore nullsオプション

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

分析関数の衝撃連載記事一覧

もっと読む

この記事の著者

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

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

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

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

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/2882 2008/10/31 14:00

イベント

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

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

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

メールバックナンバー