-- 内连接是显示连接语法-- INNER 关键字可写可不写-- 连接多表列,结果显示两张连在一起的表,orders表在前customers表在后SELECT*FROM orders
JOIN customers
ON orders.customer_id = customers.customer_id;-- SELECT 子句中 如果有列不明确的列(两个表中都有的列),需要加上前缀SELECT order_id,o.customer_id,first_name,last_name
-- 给表起别名 在表名后面空格加别名,则其他需要加表名前缀的都可以写成表别名FROM orders o
JOIN customers c
ON o.customer_id = c.customer_id;-- 练习:用order_items表连接products表查询订单id,商品id,商品件数,单价 -- *注意order_items订单列表和product商品列表中的unit_price可能存在差异,所以要注意到底需要哪个SELECT order_id,oi.product_id,quantity,oi.unit_price
FROM order_items oi
JOIN products p
ON oi.product_id = p.product_id;
2. 跨数据库连接 多个数据库的表中的列合并起来
-- 要给不在当前数据库的表加前缀,不管是被连接的表还是要连接的表-- 当前使用的表是sql_store,所以order_items不需要加前缀SELECT*FROM order_items oi
JOIN sql_inventory.products p
ON oi.product_id = p.product_id;
3. 自连接
-- 自连接的表需要起不同的别名-- 由于自己连接自己,最后显示的也是两个表列的合并,因此SELECT子句中的列选项要做优化-- 每个列也要加前缀,或者起别名,用以优化查询结果USE sql_hr;-- 查找employees表中所有员工的管理者,每一条数据包括员工和对应管理者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;
4. 多表连接
-- 查询订单id 订单日期 顾客first name 顾客last name 订单状态 连接三张表 orders customers order_statusesSELECT
o.order_id,
o.order_date,
c.first_name,
c.last_name,
os.name ASFROM orders o
-- 通过各表之间相互存在的唯一标识符进行JOIN连接,实现多表连接查询JOIN customers c
ON o.customer_id = c.customer_id
JOIN order_statuses os
ON o.status= os.order_status_id;
5. 复合连接条件
-- 如一个列表中需要另外两个及以上的表确定一个项目-- 则这个表就会超过两个及以上的主键,称之为复合主键-- order_items表中的每一列都是由order_id和product_id两个键组合指定的项目,order_item_notes表中也有这两个键SELECT*FROM order_items oi
JOIN order_item_notes oin
ON oi.order_id = oin.order_id
AND oi.product_id = oin.product_id
6. 隐式连接语法 不建议使用 如果忘记写WHERE子句得到的是交叉数据
-- 内连接SELECT*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
c.customer_id,
c.first_name,
o.order_id
FROM customers c
-- 左外连接,此时customers表为左表,此时所有坐标的customer_id和first_name都显示,不管条件正确与否-- 右外连接,此时orders表为右表,右表所有的order_id都显示出来,不管条件正确与否LEFTJOIN orders o
ON c.customer_id = o.customer_id;
8. 多表外连接 统一外连接,要么都左连,要么都右连
-- 显示所有customers表中的数据,并且显示每位顾客对应的订单id和物流姓名-- 因为使用左外连接查询,因此不管顾客是否有订单或者物流,都会显示出来SELECT
c.customer_id,
c.first_name,
o.order_id,
sh.name AS shipper
FROM customers c
LEFTJOIN orders o
ON c.customer_id = o.customer_id
-- orders左外连接shippersLEFTJOIN shippers sh
ON o.shipper_id = sh.shipper_id
ORDERBY customer_id;-- 练习:获取订单表的订单日期 订单id 顾客表的顾客first name 物流表的物流人员 订单状态表的订单状态SELECT
o.order_date,
o.order_id,
c.first_name,
sh.name AS shipper,
os.name ASstatusFROM orders o
-- 因为每个订单都是有顾客的,因此可以使用内连接JOIN customers c
ON o.customer_id = c.customer_id
-- 不是所有订单都有物流,但没有物流也要显示,因此使用左连接LEFTJOIN shippers sh
ON o.shipper_id = sh.shipper_id
-- 每个订单都有状态,无物流是1,有物流是2,因此使用内连接即可JOIN order_statuses os
ON o.status= os.order_status_id
ORDERBYstatus;
9. 自外连接
-- 以自连接为例,自连接中实现了获取员工和对应管理者,但管理者自身没有显示在输出中-- 这时候可以使用左外连接实现所有左表记录都获取use sql_hr;SELECT
e.employee_id,
e.first_name,
m.first_name AS manager
FROM employees e
LEFTJOIN employees m
ON e.reports_to = m.employee_id;
10. USING 子句
注意:使用USING子句,必须两个表中的列相同才可以使用;否则就用ON。
-- 如果连接的ON子句的两个表的列名称相同,可以替换成USING子句SELECT
o.order_id,
c.first_name,
sh.name
FROM orders o
JOIN customers c
-- 使用ON子句添加条件连接两表-- ON o.customer_id = c.customer_id;-- 当这两个表的列名称相同时,用USING子句替代ON子句USING(customer_id)JOIN shippers sh
USING(shipper_id);-- 使用USING子句查询有复合主键的表-- order_item_notes表是由order_id和product_id组成的复合主键-- 连接order_items,显示note_id 数量 单价SELECT
oin.note_id,
oi.quantity,
oi.unit_price
FROM order_items oi
JOIN order_item_notes oin
USING(order_id,product_id);
11. 自然连接 NATIONAL JOIN 不建议使用
使用自然连接的两个表,数据库引擎会自己根据相同名称的列进行查询,我们无法控制。
-- orders表和customers表中都有相同的列名称customer_idSELECT
o.order_id,
c.first_name
FROM orders o
NATURALJOIN customers c
12. 交叉连接 CROSS JOIN
第一个表的每条记录都会跟连接的表的每条记录结合,显示的数据量是N*N。
使用场景:如商品型号和商品颜色,可以使用交叉连接。
-- 交叉连接有显示语法和隐式语法-- 连接customers表和products表,交叉显示每位顾客可以对应每件商品有哪些情况SELECT
c.first_name AS customer,
p.name AS product
-- 交叉连接的显示语法 推荐使用 更清晰-- FROM customers c-- CROSS JOIN products p-- 交叉连接的隐式语法 将交叉连接的表直接写在FROM后面FROM customers c,products p
ORDERBY customer;