Mysql多表连接

参考链接

我看的视频为
【中字】SQL进阶教程 | 史上最易懂SQL教程!10小时零基础成长SQL大师!!

这里讲的很好

由于前面的比较简单,我只记录了第三章多表连接,后面如果有时间会更新

第三章 多表连接

3.1 内连接 | Inner Joins (在多张表中查询数据)

handlebars 复制代码
[INNER] JOIN 内连接
INNER可以省略不写
orders [AS] o / customer [AS] s 表名可以起别名用来下列的简便调用
但是一旦对表名起了别名,其他任何地方都不能再使用原来的表名,而必须使用新的别名
当要查询的列名在多张表都存在时,必须加上 前缀.
语法:
JOIN 表名
ON 连接方法,即找到两者中相同的,多数情况为主键
后面可继续接上JOIN ON语句来连接多张表
mysql 复制代码
SELECT order_id,c.customer_id,first_name,last_name
FROM orders o
JOIN customers c
	ON c.customer_id=o.customer_id;

运行结果

Exercise

handlebars 复制代码
--Exercise
-- 对照order items表
-- 写一段查询,把这张表和products表连接
-- 每笔订单都返回产品id和名字,连同order items表的数量和单价
mysql 复制代码
-- Exercise
-- 这里使用oi.unit_price而不是p.unit_price的原因是,
-- products可能会随时改变,而order_price才是下订单时的price
-- product_id也一样
SELECT order_id,oi.product_id,quantity,oi.unit_price
FROM order_items oi
JOIN products p
	ON p.product_id=oi.product_id;

运行结果

3.2 跨数据库连接 | Joining Across Databases

handlebars 复制代码
跨数据库连接表,即连接不在同一数据库下的表
语法:
数据库名.表名
只需在 不在该数据库下的表名前加上前缀
mysql 复制代码
USE sql_inventory;
SELECT *
FROM sql_store.order_items oi
JOIN products s
	ON oi.product_id=s.product_id;

运行结果

3.3 自连接 | Self Joins

handlebars 复制代码
自连接就是将相同的两张表通过不同的别名,
使用不同的列连接起来,
并通过不同的别名来区分表示列名
mysql 复制代码
USE sql_hr;
-- 可理解为有第一张员工表,第二张领导表
-- 员工表的reports_to与领导表的employee_id想连接形成一张大表
-- 这里因为id为37270的员工没有reports_to所以第一个表中没有了这一行
-- 由于其余所有的员工reports_to都为37270,所以第二张表中信息全为id 37270
SELECT 
	e.employee_id,
    e.first_name,
    m.employee_id AS manager_id,
    m.first_name AS manager_first_name
FROM employees e
JOIN employees m
	ON e.reports_to=m.employee_id;

运行结果

3.4 多表连接 | Joining Multiple Tables

handlebars 复制代码
使用JOIN ON进行多表连接
handlebars 复制代码
USE sql_store;
SELECT 
	order_id,
    order_date,
    first_name,
    last_name,
    name AS status
FROM orders o
JOIN customers c
	ON o.customer_id=c.customer_id
JOIN order_statuses os
	ON o.status=os.order_status_id

运行结果

Exercise

handlebars 复制代码
1.使用invoicing数据库
2.连接clients,payment_methods,payments三张表
3.查询得到订单日期,订单id,消费金额,顾客名字,支付方式
mysql 复制代码
USE invoicing;
-- client_id 顾客id
-- invoice_id 订单id
-- status 支付方式
SELECT 
	p.date,
    p.invoice_id,
    p.amount,
	c.client_id,
    c.name AS customer_name,
    pm.name AS status
FROM payments p
JOIN clients c
	ON p.client_id=c.client_id
JOIN payment_methods pm
	ON p.payment_method=pm.payment_method_id

运行结果

3.5 复合连接条件 | Compound Join Conditions

handlebars 复制代码
当一个表中不能通过一个列来唯一识别时,即这张表的结构为复合主键时
这时我们可以通过 JOIN ON AND 来连接两张表
mysql 复制代码
USE sql_store;
SELECT *
FROM order_items oi
JOIN order_item_notes oin
	ON oi.product_id=oin.product_id
    AND oi.order_id=oin.order_id

运行结果

3.6 隐式连接语法 | Implicit Join Syntax

handlebars 复制代码
虽然MYSQL中允许使用隐式连接语法,但是为了避免出错,
最好使用显式连接,因为使用显示连接让你不得不注意语法规范
相反地、使用隐式连接可能会漏写WHERE语句

以下是分别通过显式和隐式来进行内连接

mysql 复制代码
-- 显式连接语句
SELECT *w
FROM customers c
JOIN orders o
	ON c.customer_id=o.customer_id;
mysql 复制代码
-- 隐式连接语句
SELECT *
FROM customers c,orders o
-- 可能会漏写WHERE语句,造成交叉查询的结果
WHERE c.customer_id=o.customer_id;

运行结果

3.7 外连接 | Outer Joins

handlebars 复制代码
语法:
LEFT/RIGHT [OUTER] JOIN
通过外连接可以实现 ,即使不满足连接条件,也可以实现查询的效果
mysql 复制代码
-- 左连接
SELECT 
	c.customer_id,
    c.first_name,
    o.order_id
FROM customers c
LEFT JOIN orders o
	ON c.customer_id=o.customer_id
ORDER BY c.customer_id;

运行结果

mysql 复制代码
-- 右连接
SELECT 
	c.customer_id,
    c.first_name,
    o.order_id
FROM customers c
LEFT JOIN orders o
	ON c.customer_id=o.customer_id
ORDER BY c.customer_id;

运行结果

Exercise

handlebars 复制代码
-- 写一段查询,实现外连接products和order_items
-- 以实现查询得到含有quantity列为null的product_id
mysql 复制代码
SELECT 
	p.product_id,
    p.name,
    o.quantity
FROM products p
LEFT JOIN order_items o
	ON p.product_id=o.product_id
ORDER BY p.product_id;

运行结果

3.8 多表外连接 | Outer Join Between Multiple Tables

handlebars 复制代码
多表外连接和多表内连接类似
不同在于返回表中数据的数量不同
最好使用左外连接,避免使用右外连接。
因为当SQL语句数量过多时,如果存在多个连接(包含内外),此时不易辨别表的连接结构

当使用JOIN来连接orders和shippers时

mysql 复制代码
SELECT 
	c.customer_id,
	c.first_name,
	o.order_id
FROM customers c
LEFT JOIN orders o
	ON o.customer_id=c.customer_id
JOIN shippers s
	ON o.shipper_id=s.shipper_id;

运行结果

当使用LEFT JOIN来连接orders和shippers时

mysql 复制代码
SELECT 
	c.customer_id,
	c.first_name,
	o.order_id
FROM customers c
LEFT JOIN orders o
	ON o.customer_id=c.customer_id
LEFT JOIN shippers s
	ON o.shipper_id=s.shipper_id;

运行结果

Exercise

handlebars 复制代码
-- 写一段查询实现以下返回结果
mysql 复制代码
USE sql_store;
SELECT 
	order_date,
	o.order_id,
	first_name,
	s.name AS shipper,
	os.name
FROM orders o
JOIN customers c
	ON o.customer_id=c.customer_id
LEFT JOIN shippers s
	ON o.shipper_id=s.shipper_id
LEFT JOIN order_statuses os
	ON o.status=os.order_status_id
ORDER BY os.name

运行结果

3.9 自外连接 | Self Outer Jions

handlebars 复制代码
自外查询和自连接类似
不同在于返回表中数据的数量不同

当使用JOIN来自连接时

mysql 复制代码
SELECT 
	e.employee_id,
    e.first_name,
    m.first_name AS manager
FROM employees e
JOIN employees m
	ON e.reports_to=m.employee_id

运行结果

当使用LEFT JOIN来自外连接时

mysql 复制代码
SELECT 
	e.employee_id,
    e.first_name,
    m.first_name AS manager
FROM employees e
LEFT JOIN employees m
	ON e.reports_to=m.employee_id

运行结果

3.10 USING子句 | The USING Clause

handlebars 复制代码
USING子句用于替换当连接条件的列名相同时的情况
使用USING子句可以使连接条件更加清楚
USING(列名1...列名n)
mysql 复制代码
SELECT 
	o.order_id,
	c.first_name,
	s.shipper_id AS shipper
FROM customers c
JOIN orders o
	-- ON o.customer_id=c.customer_id
    USING(customer_id)
LEFT JOIN shippers s
	-- ON o.shipper_id=s.shipper_id;
    USING(shipper_id)

运行结果

Exercise

handlebars 复制代码
-- 写一段查询实现以下返回结果
mysql 复制代码
SELECT 
	date,
	c.name AS client,
	amount,pm.name
FROM payments p
JOIN payment_methods pm
	ON p.payment_method=pm.payment_method_id
JOIN clients c
	USING(client_id)

运行结果

3.11 自然连接 | Natural Joins

handlebars 复制代码
自然连接可以通过表中相同的列名进行连接
但是连接的结果不是可控的
因此在写连接语句时,应尽量避免该语句的出现
mysql 复制代码
SELECT 
	o.order_id,
    c.first_name
FROM orders o
NATURAL JOIN customers c

运行结果

3.12 交叉连接 | Cross Joins

handlebars 复制代码
交叉连接是指将两张表的中 每张表的每一列进行映射连接
连接后的表即为两张表自由组合后的表

显式写法

mysql 复制代码
USE sql_store;
SELECT 
	c.first_name AS customer,
    p.name AS product_name
FROM customers c
CROSS JOIN products p
ORDER BY c.first_name

运行结果

隐式写法

mysql 复制代码
SELECT 
	c.first_name AS customer,
    p.name AS product_name
FROM customers c,products p
ORDER BY c.first_name

Exercise

handlebars 复制代码
-- Do a cross join between shippers and products
-- using the implicit syntax
-- and then using the explicit syntax

使用交叉连接实现连接shippers表和products表
使用隐式写法,然后再使用显式写法

隐式

mysql 复制代码
SELECT *
FROM shippers,products
ORDER BY product_id

显式

mysql 复制代码
SELECT *
FROM shippers
CROSS JOIN products
ORDER BY product_id

运行结果

3.13 联合 | Unions

handlebars 复制代码
前面的连接都是不同列之间的连接
Union是行的连接,即多个行数据的连接
需要注意的是:
1.进行联合时要注意连接的列数一定要一致
2.联合后返回的列名于第一个查询返回的列名一致
mysql 复制代码
USE sql_store;
SELECT 
	order_id,
    order_date,
    'Active' AS status
FROM orders
WHERE order_date>='2019-01-01'
UNION
SELECT 
	order_id,
    order_date,
    'Archive' AS status
FROM orders
WHERE order_date<'2019-01-01';

运行结果

mysql 复制代码
SELECT name
FROM shippers
UNION
SELECT first_name
FROM customers

运行结果

mysql 复制代码
SELECT first_name
FROM customers
UNION
SELECT name
FROM shippers

运行结果

Exercise

handlebars 复制代码
-- 执行一段查询,得到以上的返回结果
-- 新增一个列,名为type,规定:
-- 1.积分小于2000为Bronze(青铜)
-- 2.积分小于等同于3000且大于等于2000为Silver(白银)
-- 3..积分大于3000为Gold(黄金)
-- 注意表中对名字进行了排序
mysql 复制代码
SELECT 
	customer_id,
    first_name,
    points,
    'Bronze' AS type
FROM customers
WHERE points<2000
UNION
SELECT 
	customer_id,
    first_name,
    points,
    'Silver' AS type
FROM customers
WHERE points>=2000 AND points<=3000
UNION
SELECT 
	customer_id,
    first_name,
    points,
    'Gold' AS type
FROM customers
WHERE points>3000
ORDER BY first_name;

运行结果

相关推荐
IT教程资源C1 小时前
(N_128)基于springboot,vue酒店管理系统
mysql·vue·前后端分离·酒店管理系统·springboot酒店
零日失眠者1 小时前
【Oracle入门到删库跑路-06】核心技能:存储过程和函数
数据库·oracle
LucidX1 小时前
Mysql 数据库部署
数据库·oracle
数据库学啊1 小时前
国产时序数据库哪个靠谱
数据库·时序数据库
网安老伯1 小时前
什么是网络安全?网络安全包括哪几个方面?学完能做一名黑客吗?
linux·数据库·python·web安全·网络安全·php·xss
瀚高PG实验室2 小时前
postgresql日期/时间数据类型中有无时区的差异使用
数据库·postgresql·瀚高数据库
用户7227868123442 小时前
SQL中的CTE用法初步(Common Table Expression公共表表达式)
sql
Elastic 中国社区官方博客2 小时前
Elasticsearch 中的文档级基于属性的访问控制 - ABAC
大数据·数据库·elasticsearch·搜索引擎·全文检索
泉城老铁2 小时前
windows服务器mysql数据库备份脚本
java·后端·mysql