SQLのfromについてまとめています。
fromは、データアクセス対象のテーブルを指定するSQL
fromは、SQL内でアクセス対象のテーブルを指定します。
以下は、employeesテーブルから、データを全件selectで取得するSQLです。
select * from employees;
【関連記事】
▶SQL select文のサンプル集 結合、ソート、別テーブル生成の記述方法は?
fromで複数のテーブルを指定するには、join指定が必須
fromで複数テーブルを指定することも可能です。ただし、指定なしで複数テーブルを指定すると、全データの全組み合わせパターンが取得されます。
mysql> select * from employees, departments, titles; +--------+------------+------------+-----------+--------+------------+---------+--------------------+--------+-----------------+------------+------------+ | emp_no | birth_date | first_name | last_name | gender | hire_date | dept_no | dept_name | emp_no | title | from_date | to_date | +--------+------------+------------+-----------+--------+------------+---------+--------------------+--------+-----------------+------------+------------+ | 10194 | 1954-01-29 | Josyula | Hofmeyr | F | 1989-05-15 | d004 | Production | 10001 | Senior Engineer | 1986-06-26 | 9999-01-01 | | 10194 | 1954-01-29 | Josyula | Hofmeyr | F | 1989-05-15 | d006 | Quality Management | 10001 | Senior Engineer | 1986-06-26 | 9999-01-01 | | 10194 | 1954-01-29 | Josyula | Hofmeyr | F | 1989-05-15 | d008 | Research | 10001 | Senior Engineer | 1986-06-26 | 9999-01-01 | | 10194 | 1954-01-29 | Josyula | Hofmeyr | F | 1989-05-15 | d007 | Sales | 10001 | Senior Engineer | 1986-06-26 | 9999-01-01 | | 10193 | 1960-06-29 | Masaru | Cheshire | M | 1991-07-28 | d009 | Customer Service | 10001 | Senior Engineer | 1986-06-26 | 9999-01-01 | | 10193 | 1960-06-29 | Masaru | Cheshire | M | 1991-07-28 | d005 | Development | 10001 | Senior Engineer | 1986-06-26 | 9999-01-01 | | 10193 | 1960-06-29 | Masaru | Cheshire | M | 1991-07-28 | d002 | Finance | 10001 | Senior Engineer | 1986-06-26 | 9999-01-01 | | 10193 | 1960-06-29 | Masaru | Cheshire | M | 1991-07-28 | d003 | Human Resources | 10001 | Senior Engineer | 1986-06 : :
複数テーブルから、欲しい情報を取得するには、一般的に結合(join)という指定が必須です。
以下は、employees(社員)テーブルと、dept_emp(部署・社員紐付けテーブル)、departments(部署)テーブルを結合してデータを取得するSQLです。
mysql> SELECT employees.emp_no, first_name, last_name, dept_name FROM employees left join dept_emp on employees.emp_no = dept_emp.emp_no left join departments on dept_emp.dept_no = departments.dept_no limit 10; +--------+------------+-----------+--------------------+ | emp_no | first_name | last_name | dept_name | +--------+------------+-----------+--------------------+ | 10001 | Georgi | Facello | Development | | 10002 | Bezalel | Simmel | Sales | | 10003 | Parto | Bamford | Production | | 10004 | Chirstian | Koblick | Production | | 10005 | Kyoichi | Maliniak | Human Resources | | 10006 | Anneke | Preusig | Development | | 10007 | Tzvetan | Zielinski | Research | | 10008 | Saniya | Kalloufi | Development | | 10009 | Sumant | Peac | Quality Management | | 10010 | Duangkaew | Piveteau | Production | +--------+------------+-----------+--------------------+ 10 rows in set (0.00 sec)
【関連記事】
▶MySQLのleft joinサンプルコード onとusingの結合条件指定の違いは?
from dual は、oracle用の対象テーブルのないSQL記述用
Oracleでは、from指定を省略することができません。そのため、システム側でdualというダミーテーブルを用意していて、以下のように使います。
select sysdate from dual; SYSDATE ----- 26-APR-20
なお、MySQLではfrom dual指定は不要ですが、OracleのSQLとの互換性を保つために、from dual指定が可能となっています。
mysql> select now(); +---------------------+ | now() | +---------------------+ | 2020-04-25 03:09:51 | +---------------------+ 1 row in set (0.05 sec) mysql> select now() from dual; +---------------------+ | now() | +---------------------+ | 2020-04-25 03:09:56 | +---------------------+ 1 row in set (0.00 sec)
fromでテーブルの別名を指定する
fromの対象テーブル指定には、asを使って別名を定義することが可能です。
以下のSQLをasを使って書き換えてみましょう。
mysql> select employees.emp_no, first_name, last_name, departments.dept_name from employees left join dept_emp on employees.emp_no = dept_emp.emp_no left join departments on dept_emp.dept_no = departments.dept_no limit 10; +--------+------------+-----------+--------------------+ | emp_no | first_name | last_name | dept_name | +--------+------------+-----------+--------------------+ | 10001 | Georgi | Facello | Development | | 10002 | Bezalel | Simmel | Sales | | 10003 | Parto | Bamford | Production | | 10004 | Chirstian | Koblick | Production | | 10005 | Kyoichi | Maliniak | Human Resources | | 10006 | Anneke | Preusig | Development | | 10007 | Tzvetan | Zielinski | Research | | 10008 | Saniya | Kalloufi | Development | | 10009 | Sumant | Peac | Quality Management | | 10010 | Duangkaew | Piveteau | Production | +--------+------------+-----------+--------------------+
以下のようにシンプルに書き換えられました。より見やすくなったのではないでしょうか。
mysql> select t1.emp_no, first_name, last_name, t3.dept_name from employees as t1 left join dept_emp as t2 on t1.emp_no = t2.emp_no left join departments as t3 on t2.dept_no = t3.dept_no limit 10;
asによる別名定義を使って、同一テーブルを別のテーブルかのように扱うセルフジョインが可能になります。
【関連記事】
▶SQLのas句で、同一テーブルに別名をつけセルフジョインするサンプルコード
まとめ
- fromはSQLの対象テーブルを指定する
- oracleではfrom省略ができないため、from dualを指定する
- fromでのテーブル指定には別名が使える。これを応用してセルフジョインが可能