【SQL】サブクエリ

SELECT句

集計結果を表示
SELECT DISTINCT
  社員コード,
  (SELECT COUNT(*) FROM 資格情報 sub WHERE main.社員コード=sub.社員コード) AS 資格の数,
  (SELECT MAX(取得日) FROM 資格情報 sub WHERE main.社員コード=sub.社員コード) AS 直近の取得日
FROM 資格情報 main

--OVERを使った方法
SELECT DISTINCT
  社員コード,
  COUNT(*) OVER(PARTITION BY 社員コード) AS 資格の数,
  MAX(取得日) OVER(PARTITION BY 社員コード) AS 直近の取得日
FROM 資格情報

資格の数と直近の取得日を集計して表示

社員コード 資格の数 直近の取得日
0001 3 2005/10/01
0004 2 2010/03/15
0006 1 2005/09/28
全行に同じ情報を表示
SELECT 
  社員コード, 
  (SELECT COUNT(*) FROM 部署マスタ) AS 部署マスタのレコード数 
FROM 社員マスタ

--OVER句を使った方法
SELECT 
  社員コード,
  COUNT(*) OVER() AS 部署マスタのレコード数 
FROM 社員マスタ

全行に部署マスタのレコード数を表示

社員コード 部署マスタのレコード数
0001 10
0002 10
0003 10

point

サブクエリの結果は1列のみ

サブクエリの結果は1行のみ(メインと1対1で紐づくイメージ)

OVER句のPARTITION BYはグループ化する項目を選択(複数指定可)

WHERE句

検索結果を条件に指定
SELECT
 *
FROM 資格情報
WHERE 社員コード IN (SELECT 社員コード FROM 社員マスタ WHERE 氏名 LIKE '高橋%')

--JOINを使った方法
SELECT
  社員コード, 資格名, 取得日 
FROM 資格情報 
  JOIN 社員マスタ USING (社員コード)
WHERE 氏名 LIKE '高橋%'

高橋から始まる名前の社員の資格情報を表示

社員コード 資格名 取得日
0001 資格A 2002/11/02
0001 資格B 2003/04/20
0002 資格C 2005/10/01
集計結果を条件に指定
SELECT
  *
FROM 資格情報
WHERE 取得日 = (SELECT MIN(取得日) FROM 資格情報)

取得日が最過去日の情報を表示

社員コード 資格名 取得日
0001 資格A 2002/11/02

point

サブクエリの結果は1列のみ

FROM句

カスタマイズしたテーブルを結合
--一番新しい日付のレコードを取得
SELECT * FROM 資格情報 JOIN 
(SELECT 社員コード, MAX(取得日) AS 取得日 FROM 資格情報 GROUP BY 社員コード) MAX
USING (社員コード,取得日)

--WIHを使ったパターン
WITH W_資格情報 AS(
  SELECT 社員コード, MAX(取得日) AS 取得日 FROM 資格情報 GROUP BY 社員コード
)
SELECT * FROM 資格情報 JOIN W_資格情報 USING (社員コード,取得日)

直近の取得日と他項目を持つテーブルを結合

--パターン1
WITH W_直近の資格情報 AS (
 SELECT *
 FROM (
  SELECT 
   *
   ,ROW_NUMBER() OVER (PARTITION BY 社員コード ORDER BY 取得日 DESC) AS SEQ
  FROM 資格情報
 ) TMP_資格情報
 WHERE SEQ = 1
)
SELECT
  社員コード
  ,氏名
  ,資格名
  ,取得日 
FROM 社員マスタ LEFT JOIN W_直近の資格情報
  USING (社員コード)

--パターン2
SELECT
  社員コード,氏名,資格名,取得日 
FROM 社員マスタ main 
  LEFT JOIN (
    SELECT 社員コード,資格名,取得日 FROM 資格情報 WHERE 取得日 IN 
	  (SELECT MAX(取得日) FROM 資格情報 GROUP BY 社員コード)
    GROUP BY 社員コード, 資格名) sub
  USING (社員コード)
社員コード 氏名 部署名 直近の取得日
0001 高橋 一生 資格B 2003/04/20
0002 高橋 二生 資格C 2005/10/01
0003 高橋 三生 NULL NULL

point

サブクエリのテーブルはエイリアス(別名)の指定が必要