#Advanced 7: サブクエリ
/*
意味:
他のステートメント内に出現する選択ステートメントはサブクエリまたは内部
クエリと呼ばれ、外側のクエリ ステートメントはメイン クエリまたは外部クエリと呼ばれます。
分類:
サブクエリが出現する位置による:
select 後:
スカラー サブクエリのみサポート
from 以降:
テーブル サブクエリをサポート
where or after Has:
スカラー サブクエリ (単一行) √Column
サブクエリ (複数行) √後ろに行
サブクエリ
が存在する (相関サブクエリ)
テーブル サブクエリは
、結果セットの行と列の数によって異なります。
スカラー サブクエリ (結果セットには 1 つの行と 1 つの列のみが含まれます)
列のサブクエリ (結果セットには 1 つの列のみと複数の行が含まれます) 行の
サブクエリ (結果セットには 1 つの行と 1 つの列が含まれます)複数の列)
テーブル サブクエリ(通常、結果セットは複数の行と複数の列です)
*/
#1. where または Hasting
/*の後
1. スカラー サブクエリ (単一行サブクエリ)
2. 列サブクエリ (複数行サブクエリ)
3. 行サブクエリ(複数列、複数行)
特徴:
① サブクエリは括弧内に配置されます。
② サブクエリは通常、条件の右側に配置されます。
③ スカラー サブクエリは通常、単一行の演算子とともに使用されます。
> < >= <= = <>
列サブクエリ。通常、any/some、all の複数行演算子とともに使用されます。
④ サブクエリの実行はメインクエリの実行より優先され、メインクエリの条件はサブクエリの結果を使用します。
*/
#1. スカラーサブクエリ
#ケース 1: アベルより給料が高いのは誰ですか?
#①Abel の給与をクエリ
する SELECT給与
FROM 従業員
WHERE last_name = 'Abel'
#②従業員情報を問い合わせ、給与を満たす>①結果
SELECT *
FROM 従業員
WHERE 給与>(
従業員から 給与を選択
WHERE last_name = 'Abel'
);
#ケース 2: job_id が従業員 No. 141 と同じで、給与が従業員 No. 143 より高い従業員の名前、job_id、給与を返します。
#①従業員番号 141 のジョブ ID を問い合わせる
SELECT job_id
FROM 従業員
WHERE 従業員 ID = 141
#②従業員番号143の給与を問い合わせ
SELECT給与
FROM従業員
WHERE従業員id = 143
#③従業員の名前、job_id、給与をクエリします。job_id=①、給与>②が必要です。
SELECT 姓、ジョブ ID、給与
FROM 従業員
WHERE ジョブ ID = (
SELECT ジョブ ID
FROM 従業員
WHERE 従業員 ID = 141
) AND 給与>(
SELECT 給与
FROM 従業員
WHERE 従業員 ID = 143
);
#ケース 3: 社内で最も給与が低い従業員の last_name、job_id、および給与を返します。
#①会社の最低賃金を問い合わせる
SELECT MIN(salary)
FROM 従業員
#②查询last_name,job_idとsalary,requiredsalary=①
SELECT last_name,job_id,salary
FROM従業員
WHERE給与=(
SELECT MIN(salary)
FROM従業員
);
#ケース 4: 最低給与が部門番号 50 の最低給与より大きい部門 ID とその最低給与を照会する
#①部門 50 の最低給与を問い合わせる
SELECT MIN(salary)
FROM 従業員
WHERE 部門 ID = 50
#②各部門の最低賃金を問い合わせる
従業員からのSELECT MIN(給与),部門 ID FROM
GROUP BY 部門 ID
#③ ②を元に画面を作成し、 min(salary)>① を満たす
SELECT MIN(salary), 部門ID
FROM 従業員
GROUP BY 部門ID
HAVING MIN(salary)>(
SELECT MIN(salary)
FROM 従業員
WHERE 部門ID = 50
);
#スカラー サブクエリの不正な使用 ----- つまり、サブクエリの結果は 1 行 1 列でなければなりません
SELECT MIN(給与),部門ID
FROM 従業員
GROUP BY 部門ID
HAVING MIN(給与)>(
SELECT 給与
FROM 従業員
WHERE 部門ID = 250
);
#2. 列サブクエリ (複数行サブクエリ) ★
#Case 1: location_id が 1400 または 1700 である部門内のすべての従業員の名前を返す
#①location_id が 1400 または 1700 の部門番号を問い合わせる
SELECT DISTINCT 部門 ID
FROM 部門
WHERE location_id IN(1400,1700)
#②従業員の名前を照会します。部門番号は①のリストのいずれかである必要があります。
SELECT 姓
FROM 従業員
WHERE 部門 ID <>ALL(
SELECT DISTINCT 部門 ID
FROM 部門
WHERE 場所 ID IN(1400,1700)
);
#ケース 2: 他の種類の仕事の job_id が「IT_PROG」であるジョブよりも給与が低い従業員の従業員番号、名前、job_id、および給与を返します。
#①「IT_PROG」部門の給与について job_id をクエリする
SELECT DISTINCT 給与
FROM 従業員
WHERE job_id = 'IT_PROG'
#②従業員番号、名前、job_id、給与のいずれかをクエリ<(①)
SELECT last_name,employee_id,job_id,salary
FROM従業員
WHERE給与<ANY(
SELECT DISTINCT給与
FROM従業員
WHERE job_id = 'IT_PROG'
) AND job_id<>'IT_PROG';
#または
SELECT last_name,employee_id,job_id,salary
FROM 従業員
WHERE 給与<(
SELECT MAX(salary)
FROM 従業員
WHERE job_id = 'IT_PROG'
) AND job_id<>'IT_PROG';
#ケース 3: job_id が 'IT_PROG' である部門の給与より給与が低い他の部門の従業員の従業員番号、名前、job_id、および給与を返します。
SELECT last_name,employee_id,job_id,salary
FROM 従業員
WHERE 給与<ALL(
SELECT DISTINCT 給与
FROM 従業員
WHERE job_id = 'IT_PROG'
) AND job_id<>'IT_PROG';
#または
SELECT last_name,employee_id,job_id,salary
FROM 従業員
WHERE 給与<(
SELECT MIN(給与)
FROM 従業員
WHERE job_id = 'IT_PROG'
) AND job_id<>'IT_PROG';
#3. 行サブクエリ (1 行と複数列、または複数行と複数列を含む結果セット)
#Case: 最小の従業員番号と最高の給与を含む従業員情報をクエリします。
#行子查询
SELECT *
FROM 従業員
WHERE (employee_id,salary)=(
SELECT MIN(employee_id),MAX(salary)
FROM 従業員
);
#共通解決策
#①最小の従業員番号を
問い合わせる SELECT MIN(employee_id)
FROMemployees
#②最高給与の問い合わせ
SELECT MAX(salary)
FROM 従業員
#③従業員情報の
クエリ SELECT *
FROM 従業員
WHERE 従業員 ID=(
SELECT MIN(従業員 ID)
FROM 従業員
)AND 給与=( 従業員から
MAX(給与) を選択
);
#2. select の後
/* は
スカラー サブクエリのみをサポートします ----- つまり、サブクエリの結果は 1 行 1 列のみになります
*/
#Case: 各部門の従業員数をクエリする
SELECT d.*,(
SELECT COUNT(*)
FROM 従業員 e
WHERE e.Department_id = d.`Department_id`
)number
FROM 部門 d;
#ケース 2: 従業員番号 = 102 で部門名をクエリする
SELECT (
SELECT 部門名,e.部門_id
FROM 部門 d
INNER JOIN 従業員e
ON d.Department_id=e.Department_id
WHERE e.employee_id=102
) 部門名。
#3. from 以降
/*
サブクエリの結果はテーブルとして使用され、エイリアスが必要です
*/
#Case: 各部門の平均給与の給与水準を問い合わせる
#①各部門の平均給与を問い合わせる
SELECT AVG(salary), 部門ID
FROM 従業員
GROUP BY 部門ID;
SELECT * FROM job_grades;
#②①の結果セットをjob_gradesテーブルに接続し、lowest_salとhighest_salの間で平均給与をフィルタリングします。
SELECT ag_dep.*,g.`grade_level`
FROM (
SELECT AVG(salary) ag,デパートメント ID
FROM 従業員
GROUP BY 部門 ID
) ag_dep
INNER JOIN job_grades g
ON ag_dep.ag BETWEEN lower_sal AND biggest_sal;
#4、背後に存在します (相関サブクエリ)
/*
構文:
存在します (完全なクエリ ステートメント)
結果:
1 または 0
*/
#主にサブステートメントの結果に使用されますか?
SELECT EXISTS(SELECT従業員_id FROM従業員 WHERE給与=300000);
#ケース 1: 従業員を含む部門名をクエリする
#in
SELECT 部門名
FROM 部門 d
WHERE d.`部門 ID` IN(
SELECT 部門 ID
FROM 部門
);
#exists
SELECT 部門名
FROM 部門 d
WHERE EXISTS(
SELECT *
FROM 従業員 e
WHERE d.`部門ID`=e.`部門ID`
);
#ケース2: 彼女のいない男性神の情報を問い合わせる
#in
SELECT bo.*
FROM ボーイズ bo
WHERE bo.id NOT IN(
SELECT ボーイフレンド ID
FROM ビューティー
)
#exists
SELECT bo.*
FROM ボーイズ bo
WHERE NOT EXISTS(
SELECT ボーイフレンド ID
FROM ビューティー b
WHERE bo.`id`=b.`boyfriend_id`
);
#--------サブクエリ関連のケース -----------#
#1. Zlotkey と同じ部門の従業員の名前と給与をクエリする
#(1) Zlotkey と同じ部門 ID をクエリします
。 SELECT 部門 ID
FROM 従業員
WHERE last_name = 'Zlotkey';
#(2) 従業員名と給与を問い合わせる
SELECT `last_name`,`salary`
FROM従業員
WHERE 部門id=(
SELECT 部門id
FROM 従業員
WHERE last_name = 'Zlotkey'
);
#2. 会社の平均給与より高い給与を持つ従業員の従業員番号、名前、給与を照会します。
#(1) 会社の平均給与をクエリします
。 SELECT AVG(salary)
FROM 従業員;
#(2) 会社の平均給与よりも給与が高い従業員の従業員番号、氏名、給与を問い合わせる
SELECT `employee_id`,`last_name`,`salary`
FROM従業員
WHERE `salary`>(
SELECT AVG(salary)
従業員から
);
#3. 各部門の給与が部門の平均給与より高い従業員の従業員番号、名前、給与を照会します。
#(1) 各部門の平均給与を問い合わせる
SELECT AVG(salary), `Department_id`
FROM `employees`
GROUP BY `Department_id`;
#(2) 各部門の部門の平均給与よりも給与が高い従業員の従業員番号、氏名、給与を問い合わせる SELECT e.`employee_id`,
e.`last_name`,e.`salary`
FROM `employees` e
JOIN (
SELECT AVG(給与) ag,`部門ID`
FROM `従業員`
GROUP BY `部門ID`
) n
ON e.`部門ID`=n.`部門ID`
WHERE e.`給与`>n.ag;
#4. 同じ部門内の名前に文字 u が含まれる従業員の従業員番号と名前をクエリします。
#(1) 名前に文字 u が含まれる従業員の部門 ID をクエリします。
SELECT DISTINCT `Department_id`
FROM `employees`
WHERE last_name LIKE '%u%';
#(2) (1)と同じ部門の従業員番号と従業員名を問い合わせる
SELECT `employee_id`,`last_name`
FROM `employees`
WHERE `Department_id` IN (
SELECT DISTINCT `Department_id`
FROM `employees`
WHERE last_name LIKE '% u%'
);
#5. location_id が 1700 の部門に勤務する従業員の従業員番号を問い合わせる
#(1) location_id が 1700 である部門 ID をクエリする
SELECT `Department_id`
FROM `Departments`
WHERE `location_id`=1700;
#(2) location_id が 1700 の部門に勤務する従業員の従業員番号を問い合わせる
SELECT `employee_id`
FROM `employees`
WHERE `Department_id` IN (
SELECT `Department_id`
FROM `Departments`
WHERE `location_id`=1700
);
#6. K_ing がマネージャーである従業員の名前と給与をクエリする
#(1)K_ing の id
SELECT `employee_id`
FROM `employees`
WHERE `last_name`='K_ing';
#(2) マネージャーが K_ing している従業員の名前と給与をクエリする
SELECT m.`last_name`,m.`salary`
FROM `employees` m
WHERE m.`manager_id` IN (
SELECT `employee_id`
FROM `employees`
WHERE `last_name `='K_ing'
);
#7. 最も給与が高い従業員の名前をクエリします。first_name と last_name を列として表示する必要があり、列名は姓.名です。
#①最高給与を問い合わせる
SELECT MAX(salary)
FROM 従業員
#②クエリ給与=①姓.名前
SELECT CONCAT(名,姓) "姓.名"
FROM 従業員
WHERE 給与=(
SELECT MAX(給与)
FROM 従業員
);
#-----サブクエリの概要-----#
1. 意味
他のステートメント内にネストされた SELECT ステートメントはサブクエリまたは内部クエリと呼ばれ、
外側のステートメントには INSERT、UPDATE、DELETE、SELECT などがあります。一般に、SELECT は外部文として使用され、
SELECT 文の場合、その文は外部クエリまたはメインクエリと呼ばれます。
2. 分類
1.
出現位置による SELECT 後:
スカラー副問合せのみサポート
FROM 後:
テーブル副問合せの後
WHERE または HAVING:
スカラー副問合せの後 カラム副問合せ行サブ問合せEXISTS: スカラー副問合せ カラム副
問合せ行副問合せ
テーブル 副 問合せ
2. 結果セットの行と列に応じて
スカラー サブクエリ (単一行サブクエリ): 結果セットが 1 行 1 列である カラム
サブクエリ (複数行サブクエリ): 結果セットが複数行 1 列である ロウ
サブクエリ: 結果セットは複数行、複数
列のサブクエリ。 : 結果セットは複数行、複数列です。
3.
WHERE または HAVING の例の後
1. スカラーサブクエリ
例: 最低給与の従業員の名前と給与を問い合わせる
①最低給与
SELECT MIN(salary) FROM 従業員
②従業員の名前と給与を問い合わせ、給与=①
SELECT last_name,salary
FROM従業員
WHERE給与=(
SELECT MIN(給与) FROM従業員
);
2. カラムクエリ
ケース:リーダーである従業員全員の名前を問い合わせる
①全従業員のmanager_idを問い合わせる
SELECT manager_id
FROMemployees
② クエリ名、従業員 ID は、①
SELECT last_name
FROM 従業員
WHERE 従業員 ID IN(
SELECT マネージャー ID
FROM 従業員
); のリストに属します。