【MySQL】多表查询

文章目录

JOIN ...... ON

  • JOIN (要联查的表) ON (联查的条件)
sql 复制代码
SELECT order_id, o.customer_id, first_name, last_name
FROM orders o
-- 可以给常用的名字进行缩写

JOIN customers c ON o.customer_id = c.customer_id
-- 根据customer_id将两个表合并在一起
sql 复制代码
-- 小小练习
SELECT order_id, o.product_id, quantity, o.unit_price
FROM order_items o
JOIN products p ON p.product_id = o.product_id

跨数据库连接

  • 给不在当前数据库的表加前缀
sql 复制代码
SELECT *
FROM order_items oi
-- 给不在当前查询库的表加上他自己的库前缀
JOIN sql_inventory.products p ON oi.product_id = p.product_id

自连接

  • 同一张表需要使用不同的别名,查询的每列前要指定别名
sql 复制代码
SELECT e.employee_id, e.first_name, m.first_name AS manager
-- 别名e
FROM employees e
-- 别名m
JOIN employees m ON e.reports_to = m.employee_id

多表连接

  • 一直往下写JOIN ON就行
sql 复制代码
SELECT o.order_id, o.order_date, c.first_name, c.last_name, os.name AS states
-- 多表连接 接着往下写JOIN ON就行
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id
JOIN order_statuses os ON o.status = os.order_status_id
sql 复制代码
-- 小小练习
SELECT p.date, p.invoice_id, p.amount,
       c.name, pm.name
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

复合连接条件

  • 使用多个条件连接表格
  • JOIN ON 1 AND 2
sql 复制代码
SELECT *
FROM order_items oi
JOIN order_item_notes oin ON oi.order_id = oin.order_Id
-- 用AND连接更多的条件
    AND oi.product_id = oin.product_id

隐式连接语法

  • 不推荐使用隐式连接语法,尽量使用显示语法JOIN ON
sql 复制代码
-- 以下两种查询结果是一样的
-- 尽量使用显示语法
SELECT *
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id

-- 隐式连接语法,但不推荐使用
-- 使用隐式连接语法时,如果忘记写WHERE了,就会得到交叉连接的结果【笛卡尔积】
SELECT *
FROM orders o, customers c
WHERE o.customer_id = c.customer_id

外连接

  • LEFT JOIN
  • RIGHT JOIN
  • 外连接:两个表在连接过程中除了返回满足连接条件的行以外,还返回左表或右表不满足连接条件的行
sql 复制代码
-- 内连接
SELECT c.customer_id, c.first_name, o.order_id
FROM  customers c
JOIN orders o ON c.customer_id = o.customer_id
ORDER BY c.customer_id;

-- 外连接:LEFT JOIN / RIGHT JOIN
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;

-- 外连接:LEFT JOIN / RIGHT JOIN
SELECT c.customer_id, c.first_name, o.order_id
FROM  customers c
-- 右连接的结果和内连接一样。
RIGHT JOIN orders o ON c.customer_id = o.customer_id
ORDER BY c.customer_id;
sql 复制代码
-- 小小练习
SELECT p.product_id, name, quantity
FROM products p
LEFT JOIN order_items oi ON p.product_id = oi.product_id;

多表外连接

sql 复制代码
-- 多表外连接
SELECT c.customer_id, c.first_name, o.order_id, sh.name AS shipper
FROM  customers c
-- o表和c表连,sh表和o表连
LEFT JOIN orders o ON c.customer_id = o.customer_id
LEFT JOIN shippers sh ON o.shipper_id = sh.shipper_id
ORDER BY c.customer_id;
sql 复制代码
-- 小小练习
SELECT o.order_date, o.order_id, c.first_name, sh.name, os.name
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id
LEFT JOIN order_statuses os ON o.status = os.order_status_id
LEFT JOIN shippers sh ON o.shipper_id = sh.shipper_id
ORDER BY status

自外连接

  • 一个表用外连接来连接自己
sql 复制代码
USE sql_hr;
SELECT e.employee_id, e.first_name, manager.first_name AS manager
FROM employees e
LEFT JOIN employees manager ON e.reports_to = manager.employee_id

USING子句

  • 使用USING可以是JOIN ON后的条件更简介
  • USING (列名)
  • USING关键字只能在不同表中的列名字完全一样的情况下使用
sql 复制代码
USE sql_store;
SELECT o.order_id, c.first_name, sh.name AS shipper
FROM orders o
JOIN customers c USING (customer_id)
LEFT JOIN shippers sh USING (shipper_id)
sql 复制代码
-- 使用JOIN ON 写法较为复杂
SELECT *
FROM order_items o
JOIN order_item_notes oin
    ON o.order_id = oin.order_Id AND
        o.product_id = oin.product_id;
-- 同样的查询,使用USING,写法简介
SELECT *
FROM order_items o
JOIN order_item_notes oin
    USING (order_id, product_id);
sql 复制代码
-- 小小练习
USE sql_invoicing;
SELECT
       p.date,
       c.name AS client,
       p.amount,
       pm.name AS name
FROM payments p
JOIN clients c USING (client_id)
-- 两个表中的列名不一致,不能用USING,只能用ON查询
JOIN payment_methods pm ON p.payment_method = pm.payment_method_id;

自然连接

  • 写起来简单,但不建议使用。数据库引擎会自己看着办去连接两个表
sql 复制代码
USE sql_store;
SELECT *
FROM orders
-- 此时数据库引擎会自己看着办,基于两个表中共同的列连接
NATURAL JOIN customers c

交叉连接

  • 和前面的隐式连接语法一样,得到笛卡尔积的结果
  • 交叉连接有隐式语法和显示语法
  • 显示语法:CROSS JOIN
  • 隐式语法,即隐式连接语法,FROM 表1, 表2
sql 复制代码
-- 显示语法
SELECT c.first_name AS customer,
       p.name AS product
FROM customers c
CROSS JOIN products p
ORDER BY c.first_name;

-- 隐式语法
SELECT c.first_name AS customer,
       p.name AS product
FROM customers c, products p
ORDER BY c.first_name;
sql 复制代码
-- 小小练习,先隐式,再显示
SELECT *
FROM products, shippers;

SELECT *
FROM products
CROSS JOIN shippers;

联合

  • 使用UNION可以合并多段查询的记录
  • 也可以基于不同表格写查询,并将结果合并到一个结果集
sql 复制代码
-- 2019年1月1日之后的订单状态为Active;
-- 之前的订单状态为Archived。用UNION可以合并这两段查询的记录。
SELECT order_id, order_date, 'Active' AS status
FROM orders
WHERE order_date >= '2019-01-01'
UNION
SELECT order_id, order_date, 'Archived' AS status
FROM orders
WHERE order_date < '2019-01-01'
  • 注意:被UNION关联的两个子句中,SELECT后查询的列的数量必须要一直,否则会报错,如下图所示。
sql 复制代码
-- 小小练习
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
-- WHERE points BETWWEN 2000 AND 3000,写法更简洁
UNION
SELECT customer_id, first_name, points, 'Gold' AS type
FROM customers
WHERE points > 3000
ORDER BY first_name
相关推荐
tatasix29 分钟前
MySQL UPDATE语句执行链路解析
数据库·mysql
南城花随雪。41 分钟前
硬盘(HDD)与固态硬盘(SSD)详细解读
数据库
儿时可乖了42 分钟前
使用 Java 操作 SQLite 数据库
java·数据库·sqlite
懒是一种态度44 分钟前
Golang 调用 mongodb 的函数
数据库·mongodb·golang
天海华兮1 小时前
mysql 去重 补全 取出重复 变量 函数 和存储过程
数据库·mysql
gma9992 小时前
Etcd 框架
数据库·etcd
爱吃青椒不爱吃西红柿‍️2 小时前
华为ASP与CSP是什么?
服务器·前端·数据库
Yz98762 小时前
hive的存储格式
大数据·数据库·数据仓库·hive·hadoop·数据库开发
武子康2 小时前
大数据-231 离线数仓 - DWS 层、ADS 层的创建 Hive 执行脚本
java·大数据·数据仓库·hive·hadoop·mysql
黑色叉腰丶大魔王2 小时前
《MySQL 数据库备份与恢复》
mysql