MySQL の基本 - マルチテーブル クエリ

この記事では、MySQL のマルチテーブル クエリについて紹介します。

複数テーブルの関係

  • 1対多(多対1)
  • 多対多
  • 一対一

1対多

ケース: 部門と従業員の
関係: 1 つの部門が複数の従業員に対応し、1 人の従業員が 1 つの部門に対応
実現: マルチパーティで外部キーを確立し、ワンパーティで主キーをポイントします

多対多

ケース: 学生とコースの
関係: 1 人の学生が複数のコースを選択でき、1 つのコースを複数の学生が受講することも可能 実装
: 少なくとも 2 つの外部キーを含む 3 番目の中間テーブルを作成し、2 つの主キーをそれぞれ関連付けます

一対一

ケース: ユーザーとユーザーの詳細
関係: 1 対 1 の関係。主に単一テーブルの分割に使用され、1 つのテーブルの基本フィールドを 1 つのテーブルに配置し、他の詳細フィールドを別のテーブルに配置して、運用効率を向上させます。 実現: いずれか
側 外部キーを追加し、相手の主キーを関連付け、外部キーが一意(UNIQUE)になるように設定します

お問い合わせ

概要: 複数のテーブルからのデータのクエリ デカルト積
: デカルト積は、数学における 2 つのセット A と B のすべての組み合わせを指します。(複数テーブルのクエリでは、無効なデカルト積を削除する必要があります)

内部結合

内部結合クエリは 2 つのテーブルの共通部分です

暗黙的な内部結合:
SELECT 字段列表 FROM 表1, 表2 WHERE 条件 ...;

明示的な内部結合:
SELECT 字段列表 FROM 表1 [ INNER ] JOIN 表2 ON 连接条件 ...;

明示的なパフォーマンスは暗黙的なパフォーマンスよりも高い

文法:

#隐式内连接
SELECT 字段列表 FROM 表列表 WHERE 条件...;

#显式内连接
SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 ON 连接条件;

例:

#查询每一个员工的姓名,以及关联的部门名称(隐式)
SELECT emp.name,dept.name FROM emp,dept WHERE emp.dept_id = dept.id;

#查询每一个员工的姓名,以及关联的部门名称(显示)
SELECT e.name,d.name FROM emp e INNER JOIN dept d ON e.dept_id = d.id;

外部結合

左外部結合:
左側のテーブルのすべてのデータと、2 つのテーブルの交差データをクエリします。
SELECT 字段列表 FROM 表1 LEFT [ OUTER ] JOIN 表2 ON 条件 ...;
これは、テーブル 1 とテーブル 2 の交差データを含む、テーブル 1 のすべてのデータをクエリするのと同等です。

右外部結合:
右側のテーブル内のすべてのデータと、2 つのテーブルの交差部分にある一部のデータをクエリします。
SELECT 字段列表 FROM 表1 RIGHT [ OUTER ] JOIN 表2 ON 条件 ...;

例:

#查询emp表的所有数据,和对应的部门信息(左外连接)
SELECT * FROM emp e LEFT OUTER JOIN dept d ON e.dept_id = d.id;

#查询dept表的所有数据,和对应的员工信息(右外连接)
SELECT d.*,e.* FROM emp e RIGHT OUTER JOIN dept d ON e.dept_id = d.id;

自己参加

現在のテーブルとそれ自体の間の接続クエリ、自己結合ではテーブル エイリアスを使用する必要があります

文法:
SELECT 字段列表 FROM 表A 别名A JOIN 表A 别名B ON 条件 ...;

自己結合クエリ。内部結合クエリまたは外部結合クエリのいずれかになります。

例:

#查询员工及其直属领导的名字
SELECT e1.name 员工,e2.name 领导 FROM emp e1 JOIN emp e2 ON e1.managerid = e2.id;

#查询所有员工emp及其领导的名字emp,如果没有领导也要查询出来
SELECT e1.*,e2.name 领导 FROM emp e1 LEFT JOIN emp e2 ON e1.managerid = e2.id;

共同クエリ

複数のクエリの結果を結合して、新しいクエリ セットを形成します
。 構文:

SELECT 字段列表 FROM 表A ...
UNION [ALL]
SELECT 字段列表 FROM 表B ...

予防:

  • UNION ALL では重複した結果が得られますが、UNION では重複した結果は得られません
  • 結合クエリは or を使用するよりも効率的であり、インデックスが無効になりません。

例:

#将薪资低于5000的员工,和年龄大于50岁的员工都查询出来。
SELECT * FROM emp WHERE salary < 5000 UNION SELECT * FROM emp WHERE age > 50 ORDER BY id ASC;
  • 結合クエリの場合、複数のテーブルの列数が一致している必要があり、フィールドの型も一致している必要があります。
  • UNION ALL は 2 つの結果セットを直接マージしますが、UNION は重複を排除します。

サブクエリ

SQL ステートメント内のネストされた SELECT ステートメントは、ネストされたクエリと呼ばれ、サブクエリとも呼ばれます
SELECT * FROM t1 WHERE column1 = ( SELECT column1 FROM t2);
サブクエリの外側のステートメントはINSERT / UPDATE / DELETE / SELECT次のいずれかになります。

サブクエリによると、結果は次のように分類できます。

  • スカラー サブクエリ (サブクエリの結果は単一の値)
  • 列サブクエリ (サブクエリの結果は列です)
  • 行サブクエリ(サブクエリの結果は1行)
  • テーブルサブクエリ (サブクエリの結果は複数の行と複数の列です)

サブクエリの位置に応じて、次のように分類できます。

  • どこの後
  • FROMの後
  • 選択後

スカラーサブクエリ

サブクエリによって返される結果は単一の値 (数値、文字列、日付など) です。
一般的に使用される演算子:- < > > >= < <=

例:

#查询销售部的所有员工信息
SELECT * FROM emp  WHERE dept_id = (SELECT id FROM dept WHERE name = '销售部');

#查询方东白之后入职的员工信息
SELECT * FROM emp WHERE entrydate > (SELECT entrydate FROM emp WHERE name = '方东白');

#查询xxx入职之后的员工信息
select * from employee where entrydate > (select entrydate from employee where name = 'xxx');

列クエリ

サブクエリによって返される結果は列 (複数行の場合もあります) であり、このサブクエリは列サブクエリと呼ばれます。

一般的に使用される演算子:IN、NOT IN、ANT、SOME、ALL
ここに画像の説明を挿入
例:

-- 查询销售部和市场部的所有员工信息
select * from employee where dept in (select id from dept where name = '销售部' or name = '市场部');

-- 查询比财务部所有人工资都高的员工信息
select * from employee where salary > all(select salary from employee where dept = (select id from dept where name = '财务部'));

-- 查询比研发部任意一人工资高的员工信息
select * from employee where salary > any (select salary from employee where dept = (select id from dept where name = '研发部'));

行サブクエリ

返される結果は 1 行です (複数列の場合もあります)。
一般的に使用される演算子:=, <, >, IN, NOT IN

例:

#查询与张无忌的薪资及直属领导都相同的员工
SELECT * FROM emp WHERE salary = (SELECT salary FROM emp WHERE name = '张无忌') AND managerid = (SELECT managerid FROM emp WHERE name = '张无忌');

#或
SELECT * FROM emp WHERE (salary,managerid) = (SELECT salary,managerid FROM emp WHERE name = '张无忌');

テーブルサブクエリ

返される結果は、複数行および複数列の
共通演算子です。IN

例:

#查询与鹿杖客、宋远桥的职位和薪资相同的员工信息

SELECT * FROM emp WHERE job IN (SELECT job FROM emp WHERE name = '鹿杖客' OR name = '宋远桥') AND salary IN (SELECT salary FROM emp WHERE name = '鹿杖客' OR name = '宋远桥');

#查询入职日期是2006-01-01之后的员工信息,及部门信息
SELECT e.*,d.name FROM emp e LEFT JOIN dept d ON e.dept_id = d.id WHERE e.entrydate > '2006-01-01';

複数テーブルのクエリの場合

#查询员工的姓名、年龄、职位、部门信息
SELECT e.name,e.age,e.job,d.name FROM emp e LEFT JOIN dept d ON e.dept_id = d.id;

#查询年龄小于30岁的员工姓名、年龄、职位、部门信息
SELECT e.name,e.age,e.job,d.name FROM emp e LEFT JOIN dept d ON e.dept_id = d.id WHERE age < 30;

#查询拥有员工的部门ID、部门名称
SELECT d.* FROM dept d WHERE d.id IN (SELECT e.dept_id FROM emp e);

#查询所有年龄大于40的员工,及其归属的部门名称;如果员工没有分配部门,也需要展示出来
SELECT e.name,d.name FROM emp e LEFT JOIN dept d ON e.dept_id = d.id WHERE e.age > 40;

#查询所有员工的工资等级
SELECT e.name,s.grade FROM emp e,salgrade s WHERE e.salary >s.losal AND e.salary <s.hisal;

#查询研发部所有员工的信息及工资等级
SELECT e.name,s.grade FROM emp e,salgrade s WHERE e.salary >s.losal AND e.salary <s.hisal AND e.dept_id = 1;

#查询研发部员工的平均工资
SELECT AVG(salary) FROM emp WHERE dept_id = 1;

#查询工资比灭绝高的员工信息
SELECT * FROM emp WHERE salary > (SELECT salary FROM emp WHERE name = '灭绝');

#查询比平均工资高的员工信息
SELECT * FROM emp WHERE salary > (SELECT AVG(salary) FROM emp);

#查询比本部门平均工资低的员工信息
SELECT * FROM emp e2 WHERE e2.salary < (SELECT AVG(e1.salary) FROM emp e1 WHERE e1.dept_id = e2.dept_id);

#查询所有的部门信息,并统计部门的员工人数
SELECT d.id,d.name,(SELECT COUNT(*) FROM emp e WHERE e.dept_id = d.id) 人数 FROM dept d;

おすすめ

転載: blog.csdn.net/baidu_33256174/article/details/130671530