JOIN是数据库的重点, 关系数据库的精髓, 通过对多个表进行连接, 扩展表之间的关系
- JOIN主要有内连接和外连接区别
- 内连接
内连接就是通过对两个表的相同元素取并集, 如果两个表中都有该条元素, 进行连接
- 外连接
外连接一般分左连接 和 右连接, 其中一个表会全部展示, 但是另外一个表如果没有, 则会展示为NULL
JOIN 一般在WHERE子句之后, 通过ON 或者USING 进行连接, 多个表需要理清关系然后进行连接,
- 为了避免倾斜, 一般小表在左, 大表在右
# JOIN
SELECT *
FROM orders
JOIN customers
ON orders.customer_id = customers.customer_id;
SELECT order_id, orders.customer_id, first_name, last_name
FROM orders
JOIN customers
ON orders.customer_id = customers.customer_id;
SELECT order_id, o.customer_id, first_name, last_name
FROM orders o
JOIN customers c
ON o.customer_id = c.customer_id;
# 也可以用隐连接, 但是不推荐使用
SELECT *
FROM orders o, customers c
WHERE o.customer_id = c.customer_id;
# 交叉连接
SELECT *
FROM orders o, customers c;
-- Exercise
SELECT order_id, oi.product_id, quantity, oi.unit_price
FROM order_items oi
JOIN products p
ON oi.product_id = p.product_id;
# 跨数据库连接
use sql_inventory;
SELECT *
FROM sql_store.order_items oi
JOIN sql_inventory.products p
ON oi.product_id = p.product_id;
-- 自连接
USE sql_hr;
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;
-- 多表连接
USE sql_store;
SELECT
o.order_id,
o.order_date,
c.first_name,
c.last_name,
os.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
USE sql_invoicing;
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;
-- 复合连接条件,有两个主键,共同识别一条记录
USE sql_store;
SELECT *
FROM order_items oi
JOIN order_item_notes oin
ON oi.order_id = oin.order_Id
AND oi.product_id = oin.product_id;
-- 外连接 OUTER JOIN
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;
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;
SELECT
c.customer_id,
c.first_name,
o.order_id
FROM orders o
RIGHT JOIN customers c
ON c.customer_id = o.customer_id
ORDER BY c.customer_id;
-- Exercies
SELECT
p.product_id,
p.name,
oi.quantity
FROM products p
LEFT JOIN order_items oi
ON p.product_id = oi.product_id;
-- 多表外连接
SELECT
p.product_id,
p.name,
oi.quantity
FROM products p
LEFT JOIN order_items oi
ON p.product_id = oi.product_id
JOIN shippers s
SELECT
c.customer_id,
c.first_name,
o.order_id
FROM orders o
RIGHT JOIN customers c
ON c.customer_id = o.customer_id
ORDER BY c.customer_id;
SELECT
c.customer_id,
c.first_name,
o.order_id,
sh.name AS shipper
FROM customers c
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;
-- Exercise
-- order_date ,order_id , first_name , shipper, status
SELECT
o.order_date,
o.order_id,
c.first_name,
sh.name AS shipper,
os.name AS status
FROM orders o
JOIN customers c
ON o.customer_id = c.customer_id
LEFT JOIN shippers sh
ON o.shipper_id = sh.shipper_id
JOIN order_statuses os
ON o.status = os.order_status_id;
-- 自连接
USE sql_hr;
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;
-- 若两个表有一样的, 可以使用USING
USE sql_store;
SELECT
o.order_id,
c.first_name,
sh.name AS name
FROM orders o
JOIN customers c
-- ON orders.customer_id = customers.customer_id;
USING (customer_id)
JOIN shippers sh
USING (shipper_id);
SELECT *
FROM order_items oi
JOIN order_item_notes oin
-- ON oi.order_id = oin.order_Id AND oi.product_id = oin.product_id;
USING (order_id, product_id);
-- Exercise
USE sql_invoicing;
SELECT
p.date,
c.name AS client,
p.amount,
pm.name
FROM payments p
JOIN clients c
USING (client_id)
JOIN payment_methods pm
ON p.payment_method = pm.payment_method_id;
-- 自然连接 不推荐使用
USE sql_store;
SELECT
o.order_id,
c.first_name
FROM orders o
NATURAL JOIN customers c;
-- 交叉链接, 每条都会连接
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;
-- Do a cross join between shippers and products
-- using the iplicit syntax
-- and then using the explicit syntax
SELECT *
FROM shippers sh, products p;
SELECT *
FROM shippers sh
CROSS JOIN products p;