ITコーディネータのシュウです。
久しぶりに新宿のほうに仕事で行く用事があり、昼休みに新宿中央公園から都庁を撮った写真です。
話は変わりますが、先日の母の日に、子供たちが一人ひとり、妻にプレゼントをしていました。娘の一人はイヤリングのようなものをプレゼントしていたようです。まだ中学に入ったばかりの長男は、少し立派なチョコレートをあげてました。妻もまんざらではないようです。
私は妻と一緒にちょっとしたお買いものにお付き合い。妻の頑張りは大きいですよね。感謝しないと!
父の日は、何かあるかな~!
<本日の題材>
INTERSECT演算子
前回、集合演算の差を行う関数としての、MINUS、EXCEPT関数について見ましたが、今日はINTERSECTという、積集合(ただし、重複するデータについては1行にまとめる)を取得する演算子について見てみます。
積集合とは、与えられた集合の集まり全てに共通に含まれている要素を集めることにより得られる集合のこと。論理演算子ANDに相当し、共通集合もしくは「交わり」とも呼ばれます。
複数のSELECT文での問い合わせの結果に対して、共通の集合を重複しないかたちで抽出します。
なお、この演算子は、Oracle、SQL Serverともで使用できます。
例1)
前回の抽出で使用したtbl_A、tbl_Bを利用して、どちらのテーブルにも存在する全く同じ値のレコードを抽出してみます。
(SQL Serverで確認)
SELECT * FROM tbl_A
INTERSECT
SELECT * FROM tbl_B;
前回、tbl_A、tbl_B のデータを確認していますが、たしかに、tbl_A、tbl_B のどちらにも存在するレコードが抽出されました。
例2)
あるメーカーの3月に行ったキャンペーンに応募した顧客のデータを、「CP_応募」テーブルに登録したとします。
データは以下:
①
SELECT * FROM dbo.CP_応募
ORDER BY 顧客ID;
次に、上記のキャンペーンに応募した顧客も含めて、4月の売上金額の多い顧客について、売上金額が1万円以上の顧客を金額の高い順に抽出した結果が以下とします。
②
SELECT
ROW_NUMBER() OVER (ORDER BY SUM(売上金額) DESC) AS 売上順位
, 顧客ID
, SUM(売上金額) AS 売上合計
FROM dbo.売上
WHERE FORMAT(出荷日, 'yyyyMM') = '201504'
GROUP BY 顧客ID
HAVING SUM(売上金額) >= 10000
ORDER BY SUM(売上金額) DESC;
上記の①と②の結果で、どちらにも存在する顧客IDを抽出したいというときに、INTERSECT関数を使用してみます。
SELECT 顧客ID
FROM dbo.CP_応募
INTERSECT
SELECT 顧客ID
FROM dbo.売上
WHERE FORMAT(出荷日, 'yyyyMM') = '201504'
GROUP BY 顧客ID
HAVING SUM(売上金額) >= 10000
ORDER BY 顧客ID;
3月のCPに応募した顧客が、4月の売上の上位(1万円以上)に5人含まれていることが確認できました。
ただ、これは「CP_応募」テーブルと「売上」テーブルを、下記SQLのように「顧客ID」でジョインして抽出するということでも同様の結果が出ます。というか、どちらかというと、ジョインを使うのが一般的なやり方かとは思われますが。
SELECT A.顧客ID
FROM dbo.売上 A
JOIN dbo.CP_応募 B ON A.顧客ID = B.顧客ID
WHERE FORMAT(A.出荷日, 'yyyyMM') = '201504'
GROUP BY A.顧客ID
HAVING SUM(A.売上金額) >= 10000
ORDER BY A.顧客ID;
このINTERSECT演算子は、Oracleでも同様に使用することができます。
例1)について、Oracle環境で実施した結果は、以下になります。
ちなみに、MySQLではやはりINTERSECT演算子は対応していないようなので、EXISTS句を利用するなどして、全ての項目が一致するレコードを抽出することになります。
今日は以上まで
にほんブログ村