表连接

admin

表连接语法

为了解决这个问题,SQL提供表连接语句来实现不同表之间的数据连接,它们由以下的数据库连接语句构成:

表达式

含义

[INNER] JOIN 表格 ON 连接字段

通过两个表格共有的连接字段将两张表进行连接,只会展示两张表都有的公共数据

LEFT JOIN 表格 ON 连接字段

用于表示按照左边表格作为主表格,完全展示左边的表格数据, 右边的表格有和左边的表格一样的连接字段则展示数据,没有一样的连接字段则省略,数据为NULL值

RIGHT JOIN 表格 ON 连接字段

用于按照右边表格作为主表格,完全展示右边的表格数据,左边的表格有和右边的表格相同的连接字段则展示数据,没有相同的连接字段则省略,数据为NULL值

FULL JOIN 表格 ON 连接字段

从语句结果上来说,相当于既做了LEFT JOIN 又做了 RIGHT JOIN。会全量展示左右两边表格的所有数据,如果某一边没有该条数据,则数据展示为NULL值。MySQL没有这个功能,不过魔改版如ADB等有这个功能。

思考题的解法

在了解了表连接的语法之后,我们再回到思考题的卡点问题上。要想将订单表和订单明细表连接起来,首先要找到订单表和订单明细表之间的连接字段。因此,得回到这两张表的表结构上:

order_item表

字段名注释
id订单明细ID
order_id订单ID
goods_id商品ID
goods_name商品名称
category_name_4一级类目
category_name_3二级类目
category_name_2三级类目
category_name_1四级类目
real_amount实际货值
real_count实际件数
real_weight实际重量

order表

字段名注释
id订单ID
create_time订单创建时间
customer_store_id店铺ID
province_name收货省
city_name收货市
county_name收货区县
street_name收货街道
status订单状态
bd_idBDID
payment_amount实付金额

仔细查看这两张表的结构之后,我们会发现两张表共有订单ID这个字段,因此针对order表和order_item表我们可以使用订单ID进行连接,至于左连接还是右连接这个关系不是很大,只要你确定好用哪个作为主表,左右连接是可以做转换的。因此可以写为:

-- 右连接写法
FROM `order` t1
RIGHT JOIN order_item t2 ON t1.id = t2.order_id


-- 左连接写法
FROM `order_item` t1
LEFT JOIN `order` t2 ON t1.order_id = t2.id

整个思考题的语法可以写为:

-- 左连接写法
SELECT SUM(t1.real_amount) all_amount -- 所有货值
        ,SUM(IF(t2.status = 'CANCEL',t1.real_amount,NULL)) cancel_amount -- 取消单货值
        ,SUM(IF(t1.goods_name LIKE '%爆品%' AND t1.goods_name NOT LIKE '%超级爆品%',t1.real_amount,NULL)) explosives_amount -- 爆品货值
        ,SUM(IF(t1.goods_name LIKE '%超级爆品%',t1.real_amount,NULL)) super_explosives_amount -- 超级爆品货值
FROM order_item t1
LEFT JOIN `order` t2
        ON t1.order_id = t2.id 
WHERE YEAR(t2.create_time) = 2022 AND MONTH(t2.create_time) = 8 



-- 右连接写法
SELECT SUM(t2.real_amount) all_amount -- 所有货值
        ,SUM(IF(t1.status = 'CANCEL',t2.real_amount,NULL)) cancel_amount -- 取消单货值
        ,SUM(IF(t2.goods_name LIKE '%爆品%' AND t2.goods_name NOT LIKE '%超级爆品%',t2.real_amount,NULL)) explosives_amount -- 爆品货值
        ,SUM(IF(t2.goods_name LIKE '%超级爆品%',t2.real_amount,NULL)) super_explosives_amount -- 超级爆品货值
FROM `order` t1
LEFT JOIN `order_item` t2
        ON t2.order_id = t1.id 
WHERE YEAR(t1.create_time) = 2022 AND MONTH(t1.create_time) = 8

例题

  1. 获得2022年8月份,由姓毛或者姓杨的各个BD负责的店铺下单货值、实付金额、取消单货值、取消单实付金额、订单数、取消单订单数。

首先分析题:

  1. 需要知道员工的姓氏,数据来源是员工表staff,需要知道下单货值,数据来源是订单明细表order_item,需要知道订单状态、订单时间和实付金额,数据来源是订单表order

  2. 员工表和订单表之间有bd_id进行连接,订单表和订单明细表之间有订单ID进行连接。

SELECT t1.bd_id 
        ,t3.bd_name 
        ,SUM(t2.real_amount) real_amount
        ,SUM(t1.payment_amount) payment_amount 
        ,SUM(IF(t1.status = 'CANCEL',t2.real_amount,NULL)) cancel_amount
        ,SUM(IF(t1.status = 'CANCEL',t1.payment_amount,NULL)) cancel_money
        ,COUNT(DISTINCT t1.id) order_number
        ,COUNT(DISTINCT IF(t1.status = 'CANCEL',t1.id,NULL)) cancel_orders
FROM `order` t1
LEFT JOIN order_item t2
        ON t1.id = t2.order_id 
LEFT JOIN staff t3
        ON t1.bd_id = t3.bd_id 
WHERE YEAR(t1.create_time) = 2022
        AND MONTH(t1.create_time) = 8
        AND (t3.bd_name LIKE '毛%' OR t3.bd_name LIKE '杨%')
GROUP BY t1.bd_id 
        ,t3.bd_name



返回顶部