MySQL 学習メモ ------ サブクエリ


#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 従業員
); のリストに属します。

おすすめ

転載: blog.csdn.net/weixin_47156401/article/details/131927945