SHOEISHA iD

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

連載記事

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

CodeZine BOOKS(コードジン・ブックス)は、CodeZineの連載からカットアップした、開発現場の課題解決に役立つ書籍シリーズです。

書籍に関する記事を見る

'); googletag.cmd.push(function() { googletag.pubads().addEventListener('slotRenderEnded', function(e) { var ad_id = e.slot.getSlotElementId(); if (ad_id == 'div-gpt-ad-1659428980688-0') { var ad = $('#'+ad_id).find('iframe'); if ($(ad).width() == 728) { var ww = $(window).width(); ww = ww*0.90; var style = document.createElement("style"); document.head.appendChild( style ); var sheet = style.sheet; sheet.insertRule( "#div-gpt-ad-1659428980688-0 iframe {-moz-transform: scale("+ww/728+","+ww/728+");-moz-transform-origin: 0 0;-webkit-transform: scale("+ww/728+","+ww/728+");-webkit-transform-origin: 0 0;-o-transform: scale("+ww/728+","+ww/728+");-o-transform-origin: 0 0;-ms-transform: scale("+ww/728+","+ww/728+");-ms-transform-origin: 0 0;}", 0 ); sheet.insertRule( "#div-gpt-ad-1659428980688-0 div{ height:"+(90*ww/728)+"px;width:"+728+"px;}", 0 ); } else { if ($(window).width() < 340) { var ww = $(window).width(); ww = ww*0.875; var style = document.createElement("style"); document.head.appendChild( style ); var sheet = style.sheet; sheet.insertRule( "#div-gpt-ad-1659428980688-0 iframe {-moz-transform: scale("+ww/320+","+ww/320+");-moz-transform-origin: 0 0;-webkit-transform: scale("+ww/320+","+ww/320+");-webkit-transform-origin: 0 0;-o-transform: scale("+ww/320+","+ww/320+");-o-transform-origin: 0 0;-ms-transform: scale("+ww/320+","+ww/320+");-ms-transform-origin: 0 0;}", 0 ); sheet.insertRule( "#div-gpt-ad-1659428980688-0 div{ height:"+(180*ww/320)+"px;width:"+320+"px;}", 0 ); } } } }); }); } else { document.write('
'); document.write('
'); }
分析関数の衝撃

分析関数の衝撃(中編)

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


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

ダウンロード ソースコード (4.2 KB)

SQLを使う業務では、分析関数を使いこなすと、生産性と、SQLの可読性とパフォーマンスを、大きく向上させることができます。分析関数を使う際の、考え方と、処理のイメージを解説します。

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

はじめに

 「分析関数の衝撃(前編)」に引き続き、CodeZineのミック氏の記事で記載されたSQLを、分析関数を使って記述していきます。

対象読者

  • SQLの可読性を向上させたい方
  • SQLのパフォーマンスを向上させたい方

 この記事では、「自己結合の使い方」と、「相関サブクエリで行と行を比較する」に記載されているSQLを分析関数を使って記述していきますので、先に読まれた方が理解がしやすいと思います。

必要な環境

 本稿で扱うSQLは、Oracle 10.2.0.1.0で動作確認しました。ソースコードはDB2 V9.1でも動作確認しました。その他、

  • Oracle9i以降
  • DB2
  • SQL Server 2005

 でも応用できます。

1. 部分的に不一致なキーの検索

 まずは部分的に不一致なキーを検索するSQLについてです。「自己結合の使い方」では、以下の自己非等値結合を使うSQLが提示されています。

同じ家族だけど、住所が違うレコードを検索するSQL
SELECT DISTINCT A1.name, A1.address
  FROM Addresses A1,
       Addresses A2
 WHERE A1.family_id = A2.family_id
   AND A1.address <> A2.address ;

 これを分析関数で書き換えてみます。まずは、少しデータを変更した「Addresses」テーブルのデータと出力結果を考えます。

Addressesテーブル
namefamily_idaddress
前田 義明100港区虎ノ門3-2-29
前田 由美100港区虎ノ門3-2-92
加藤 茶200新宿区西新宿2-8-1
加藤 勝200新宿区西新宿2-8-1
ホームズ300ベーカー街221B
ワトソン400ベーカー街221B
織田 信長500京都
織田 信忠500京都
織田 長益500京都
徳川 家康600関ヶ原
松平 忠吉600関ヶ原
徳川 秀忠600上田城
出力結果
nameaddress
前田 義明港区虎ノ門3-2-29
前田 由美港区虎ノ門3-2-92
徳川 家康関ヶ原
松平 忠吉関ヶ原
徳川 秀忠上田城

 手続き型の言語であれば、

  1. family_idの昇順にソート
  2. family_idの最小値からループ開始
  3. family_idの値を変数に保存
  4. addressの値を変数に保存
  5. addressの値が違ったら出力
  6. family_idがブレイクしたら、3へ
  7. family_idがブレイクしなかったら、5へ

 といった処理を行うと思いますが、分析関数を使ったSQLでも似たような考え方を使います。

分析関数で書き換えたSQL
select name,address
from (select name,address,
      count(distinct address)
      over(partition by family_id) as distinctAddressCount
        from Addresses)
where distinctAddressCount > 1;

 partition by句に「family_id」を指定して、「family_id」が等しい部分集合でのcount(distinct address)を求めてます。partition by句を使ったSQLのイメージは、こうなります。

partition by句を使ったSQLのイメージ
partition by句を使ったSQLのイメージ

 後は、count(distinct address)が、1より大きいことを、外側のselect文のwhere句で条件としてます。同じ「family_id」で、「address」が2通り以上あったら、出力対象になるという考え方です。

 DB2では、分析関数のcount関数でdistinctオプションが使えないので、下記のSQLとなります。

分析関数で書き換えたSQL(DB2)
--逆ソートを使って、
--count(distinct address) over(partition by family_id)を求める方法
select name,address
  from (select name,address,
        -1+dense_rank()
           over(partition by family_id order by address asc)
          +dense_rank()
           over(partition by family_id order by address desc)
      as distinctAddressCount
        from Addresses) dummy
where distinctAddressCount > 1;

--最小値と最大値が異なれば、住所が2件以上あると考える方法
select name,address
  from (select name,address,
        max(address) over(partition by family_id) as MaxAddress,
        min(address) over(partition by family_id) as MinAddress
          from Addresses) dummy
where MaxAddress != MinAddress;

会員登録無料すると、続きをお読みいただけます

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

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

メールバックナンバー

次のページ
2. 前年と年商が同じ年度を求める

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

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

もっと読む

この記事の著者

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

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

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

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

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/1298 2007/09/04 12:39
" ); }

おすすめ

アクセスランキング

  1. 1
    大企業を芯からアジャイルに──20年以上アジャイル実践してきた市谷氏が語る変革への道
  2. 2
    アジャイル開発の推進において、必ずしも"すごい人"は必要ない──現場のエンジニアがDevOps推進で実現する組織改革
  3. 3
    ガントチャートをWebアプリに組み込める「ガントシート」でプロジェクト管理機能を作成してみよう
  4. 4
    Renewer、Tips集「生成AI × 勉強法ガイドブック 2025」を公開
  5. 5
    いいエンジニアになるための2つのポイント ──元Google技術者・石原氏が説く「シリコンバレー流ソフトウェア開発術」
  1. 6
    【成長するための1on1完全攻略術】意義を理解して効果的なミーティングを行うための準備をしよう! NEW
  2. 7
    NVIDIA、AIスーパーコンピューター「Project DIGITS」を発表 NEW
  3. 8
    より良いプロダクトを作り続けるために ――ソフトウェアエンジニアのための3つのキャリア構築マインドセット
  4. 9
    Node.js v23.6.0 リリース、TypeScriptの実行が容易に
  5. 10
    Meta社開発のSSG、「Docusaurus 3.7」リリース NEW

アクセスランキング

  1. 1
    大企業を芯からアジャイルに──20年以上アジャイル実践してきた市谷氏が語る変革への道
  2. 2
    アジャイル開発の推進において、必ずしも"すごい人"は必要ない──現場のエンジニアがDevOps推進で実現する組織改革
  3. 3
    ガントチャートをWebアプリに組み込める「ガントシート」でプロジェクト管理機能を作成してみよう
  4. 4
    Renewer、Tips集「生成AI × 勉強法ガイドブック 2025」を公開
  5. 5
    いいエンジニアになるための2つのポイント ──元Google技術者・石原氏が説く「シリコンバレー流ソフトウェア開発術」
  6. 6
    【成長するための1on1完全攻略術】意義を理解して効果的なミーティングを行うための準備をしよう! NEW
  7. 7
    NVIDIA、AIスーパーコンピューター「Project DIGITS」を発表 NEW
  8. 8
    より良いプロダクトを作り続けるために ――ソフトウェアエンジニアのための3つのキャリア構築マインドセット
  9. 9
    Node.js v23.6.0 リリース、TypeScriptの実行が容易に
  10. 10
    Meta社開発のSSG、「Docusaurus 3.7」リリース NEW
  1. 1
    アジャイル開発の推進において、必ずしも"すごい人"は必要ない──現場のエンジニアがDevOps推進で実現する組織改革
  2. 2
    いいエンジニアになるための2つのポイント ──元Google技術者・石原氏が説く「シリコンバレー流ソフトウェア開発術」
  3. 3
    ガントチャートをWebアプリに組み込める「ガントシート」でプロジェクト管理機能を作成してみよう
  4. 4
    1/10まで全文無料公開、人気の入門書シリーズ『いきなりプログラミング Androidアプリ開発』
  5. 5
    デスクトップアプリ開発に必要な「Rust」の文法を理解しよう
  6. 6
    "けしからん"精神が切り拓く未来──IPA登氏が語る、技術大国・日本が目指す復活戦略
  7. 7
    Google、社内AIエージェント「Google Agentspace」発表
  8. 8
    JavaScriptのWebフレームワーク、「Astro 5.1」リリース
  9. 9
    「CUDA」 ~マンガでプログラミング用語解説
  10. 10
    テストは増え続ける、でもボトルネックにはできない──テスト効率化の2つのカギを朱峰 錦司氏が解説!

イベント

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

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

メールバックナンバー

アクセスランキング

  1. 1
    大企業を芯からアジャイルに──20年以上アジャイル実践してきた市谷氏が語る変革への道
  2. 2
    アジャイル開発の推進において、必ずしも"すごい人"は必要ない──現場のエンジニアがDevOps推進で実現する組織改革
  3. 3
    ガントチャートをWebアプリに組み込める「ガントシート」でプロジェクト管理機能を作成してみよう
  4. 4
    Renewer、Tips集「生成AI × 勉強法ガイドブック 2025」を公開
  5. 5
    いいエンジニアになるための2つのポイント ──元Google技術者・石原氏が説く「シリコンバレー流ソフトウェア開発術」
  1. 6
    【成長するための1on1完全攻略術】意義を理解して効果的なミーティングを行うための準備をしよう! NEW
  2. 7
    NVIDIA、AIスーパーコンピューター「Project DIGITS」を発表 NEW
  3. 8
    より良いプロダクトを作り続けるために ――ソフトウェアエンジニアのための3つのキャリア構築マインドセット
  4. 9
    Node.js v23.6.0 リリース、TypeScriptの実行が容易に
  5. 10
    Meta社開発のSSG、「Docusaurus 3.7」リリース NEW

アクセスランキング

  1. 1
    大企業を芯からアジャイルに──20年以上アジャイル実践してきた市谷氏が語る変革への道
  2. 2
    アジャイル開発の推進において、必ずしも"すごい人"は必要ない──現場のエンジニアがDevOps推進で実現する組織改革
  3. 3
    ガントチャートをWebアプリに組み込める「ガントシート」でプロジェクト管理機能を作成してみよう
  4. 4
    Renewer、Tips集「生成AI × 勉強法ガイドブック 2025」を公開
  5. 5
    いいエンジニアになるための2つのポイント ──元Google技術者・石原氏が説く「シリコンバレー流ソフトウェア開発術」
  6. 6
    【成長するための1on1完全攻略術】意義を理解して効果的なミーティングを行うための準備をしよう! NEW
  7. 7
    NVIDIA、AIスーパーコンピューター「Project DIGITS」を発表 NEW
  8. 8
    より良いプロダクトを作り続けるために ――ソフトウェアエンジニアのための3つのキャリア構築マインドセット
  9. 9
    Node.js v23.6.0 リリース、TypeScriptの実行が容易に
  10. 10
    Meta社開発のSSG、「Docusaurus 3.7」リリース NEW
  1. 1
    アジャイル開発の推進において、必ずしも"すごい人"は必要ない──現場のエンジニアがDevOps推進で実現する組織改革
  2. 2
    いいエンジニアになるための2つのポイント ──元Google技術者・石原氏が説く「シリコンバレー流ソフトウェア開発術」
  3. 3
    ガントチャートをWebアプリに組み込める「ガントシート」でプロジェクト管理機能を作成してみよう
  4. 4
    1/10まで全文無料公開、人気の入門書シリーズ『いきなりプログラミング Androidアプリ開発』
  5. 5
    デスクトップアプリ開発に必要な「Rust」の文法を理解しよう
  6. 6
    "けしからん"精神が切り拓く未来──IPA登氏が語る、技術大国・日本が目指す復活戦略
  7. 7
    Google、社内AIエージェント「Google Agentspace」発表
  8. 8
    JavaScriptのWebフレームワーク、「Astro 5.1」リリース
  9. 9
    「CUDA」 ~マンガでプログラミング用語解説
  10. 10
    テストは増え続ける、でもボトルネックにはできない──テスト効率化の2つのカギを朱峰 錦司氏が解説!