SQL:相関サブクエリ, コメント

### SQL 読み込まれる順番

1. FROM: クエリの対象となるテーブル(またはビュー)を指定
2. WHERE: 条件に基づいて行を取得
3. GROUP BY: グループ化の基準となる列を指定
4. HAVING: GROUP BY で取得した結果をさらに 絞る
5. SELECT: フィルタリングおよびグループ化されたデータから必要な列を選択
6. ORDER BY: 結果の並べ替え。 ASC, DESC など
7. LIMIT(またはTOPなど): 取得する行を指定し制限する
SQL分の中でのコメントの書き方
1. 
/*
上下2つの記号(/**/)を使って、挟んだ範囲が、
コメントになる
*/

2.
-- ここがコメントになる。

ハイフン2つ + 半角スペース1つ

3.
# シャープの横が、コメントになる。

シャープ1つ + 半角スペース1つ

例:
/*
給与が平均以上の従業員番号
*/
SELECT
  DISTINCT(emp_no) -- 従業員番号の重複を排除
FROM
  salaries # 給与テーブル
WHERE
  salary >= salary の平均値
LIMIT 10;

相関サブクエリ

# salary が平均以上の emp_no を取得する

SELECT
  DISTINCT(emp_no)
FROM
  salaries
WHERE
  salary >= (
              SELECT
                AVG(salary)
              FROM
                salaries
            )
LIMIT 10;

上記は、以下を意味している。

SELECT
  DISTINCT(emp_no)
FROM
  salaries
WHERE
  salary >= salary の平均値
LIMIT 10;
  • DISTINCT(emp_no):emp_no の重複を除外して、ユニークな emp_no のみにしている。

  • 平均の2倍以上 :AVG(salary) * 2

/*
番号 10001 ~ 10100 の中で、それぞれの性別で最高年齢の人の性別、
誕生日、first_name, last_name を抽出する。
*/

SELECT
  gender,
  birth_date,
  first_name,
  last_name
FROM
  employees AS e1
WHERE
  emp_no BETWEEN 10001 AND 10100
  AND birth_date =  (
                      SELECT
                        MIN(birth_date)
                      FROM
                        employees AS e2
                      WHERE
                        emp_no BETWEEN 10001 AND 10100
                        AND e1.gender = e2.gender
                      GROUP BY gender
                    )
;

+--------+------------+------------+-------------+
| gender | birth_date | first_name | last_name   |
+--------+------------+------------+-------------+
| F      | 1952-04-19 | Sumant     | Peac        |
| M      | 1952-02-27 | Remzi      | Waschkowski |
+--------+------------+------------+-------------+
2 rows in set
/*
employees テーブルの中で、emp_no が 10,001 ~ 10,100 の中で、かつ
それぞれのジェンダーの中で、誕生日が1番古いの を抽出する
*/

mysql> SELECT
    ->   MIN(birth_date),
    ->   gender
    -> FROM
    ->   employees
    -> WHERE
    ->   emp_no BETWEEN 10001 AND 10100
    -> GROUP BY gender
    -> ;
+-----------------+--------+
| MIN(birth_date) | gender |
+-----------------+--------+
| 1952-02-27      | M      |
| 1952-04-19      | F      |
+-----------------+--------+
2 rows in set
# 各従業員の最高給与の上位30位の従業員番号と最高給与金額を求めよう

SELECT 
  emp_no,
  salary
FROM 
  salaries
WHERE 
  salary IN (
              SELECT 
                DISTINCT(salary)
              FROM 
                salaries
              ORDER BY 
                salary DESC
            )
ORDER BY 
  salary DESC
LIMIT 30;
+--------+--------+
| emp_no | salary |
+--------+--------+
|  43624 | 158220 |
|  43624 | 157821 |
| 254466 | 156286 |
...
...
...
| 266526 | 151080 |
| 237542 | 150994 |
| 493158 | 150993 |
+--------+--------+
30 rows in set