So-net無料ブログ作成
検索選択

クエリ グループで最大値をもつレコードの抽出(相関サブクエリ) [クエリ]

 以前の記事で、テーブル全体から最大値をもつレコードを抽出する方法をとりあげましたが、今回はグループ毎の最大値のレコードを抽出します。

 データはこんな感じ。
 担当Aさん、Bさん、Cさん・・・が居て、日付毎に、金額が一番大きかった人のレコードを抽出します。

 まず、以前と同じ考え方でSQLを作成します。
 日付毎に最大の金額を求めるSQLを作成します。

SELECT 日付, Max(T実績.金額) AS 金額
FROM T実績
GROUP BY 日付

 結果は、以下の通り。

 日付と金額が得られたので、これと一致するレコードを抽出するSQLを書けばできあがりです。
 しかし、前回のSQLの、
SELECT 日付, 金額
FROM T売上
WHERE 金額 = ( SELECT MAX( 金額 ) FROM T売上 )

 という方法は、サブクエリの結果が1件のときしか利用できません。今回は、条件にしたい項目も2つあります。
 なので、今回は、WHERE条件ではなく、テーブル結合で抽出します。

SELECT A.日付,A.担当,A.金額
FROM T実績 AS A INNER JOIN
(SELECT T実績.日付, Max(T実績.金額) AS 金額
FROM T実績
GROUP BY T実績.日付) AS B
ON (A.金額 = B.金額) AND (A.日付 = B.日付)


 一致のみで良いので、INNER JOINで結合します。

 最終結果。

 該当レコードが抽出できました。

○相関サブクエリの例

 さて、上記の方法でも目的の結果が得られますが、別のやり方もあります。

SELECT A.日付,A.担当,A.金額
FROM T実績 AS A
WHERE A.金額=
( SELECT MAX(B.金額)
FROM T実績 AS B
WHERE B.日付 = A.日付 )

 こういう書き方です。

 親のクエリのWHERE条件に、サブクエリを使っているところは、前回ケースのSQLに似ています。
 しかし、サブクエリに、「WHERE A.日付 = B.日付」という、条件があります。
 このようなサブクエリは、相関サブクエリというらしいです。

 このSQLがどのように処理されるか、順を追って説明します。
 まず、親クエリのテーブルから、1件レコードを取り出し、評価されます。
 テーブルの1件目、「2012/01/01・A・990」のレコードが取り出されたとします。

 このレコード内容に対して、サブクエリが実行されます。
 具体的には、サブクエリの「A.日付」に、レコードの値が設定された、
SELECT MAX(B.金額)
FROM T実績 AS B
WHERE B.日付 = #2012/01/01#

 が、実行されます。
 2012/01/01の最大金額は、1900ですので、この値がサブクエリの結果になります。

 この結果を元に、親クエリのWHERE条件
WHERE A.金額=
( SELECT MAX(B.金額)
FROM T実績 AS B
WHERE B.日付 = A.日付 )

 は、
WHERE 990=1900
 という内容になります。
 この条件は成立していませんので、1件目のレコードは結果として抽出されません。

 これと同じ事を3件目のデータ、「2012/01/01・C・1900」でやると、
WHERE 1900=1900
 
となり、成立するので、このレコードは結果として抽出されます。

 つまり、相関サブクエリは、親クエリのレコード1件に対して、サブクエリが1回実行されます。

 全レコードの処理イメージを表にすると、以下のような感じです。

 イコールが成り立ったレコードが、結果に抽出される、といった具合です。

 相関サブクエリは、親クエリから1件ずつ処理される、と言う事を念頭に置いて、レコードのデータを当てはめながら処理を追ってみると、分かり易いと思います。



【2万円から3万円の、格安ホームページ作成サービス】

nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

※ブログオーナーが承認したコメントのみ表示されます。
※URL(リンク)は記述できません。

トラックバック 0

トラックバックの受付は締め切りました