补充知识:笛卡尔积演示

如何理解笛卡尔积

多表关联的原理是把关联的表进行笛卡尔积

  • 先取出两张表
-- 1、先取出两表中A005和AO19的记录作为初始表
select *
from db_order.sn_order_20210412
where id in ('A005','A019');
select *
from db_order.sn_orderitem_20210412
where order_id in ('A005','A019');
sn_order_20140412
订单号订单金额会员号创建时间订单状态
A0051200.1552017/1/1 13:232
A01999122017/2/11 13:231
sn_orderitem_20210412
订单商品ID订单号商品ID商品名称商品价格商品数量
AB004A0051001A0.151
AB005A0051004D2006
AB0016A0191006F501
AB0017A0191007G24.52
  •  手动进行笛卡尔积演示
手动_笛卡尔积
订单号订单金额会员号创建时间订单状态订单商品ID订单号商品ID商品名称商品价格商品数量
A0051200.1552017/1/1 13:232AB004A0051001A0.151
A0051200.1552017/1/1 13:232AB005A0051004D2006
A0051200.1552017/1/1 13:232AB0016A0191006F501
A0051200.1552017/1/1 13:232AB0017A0191007G24.52
A01999122017/2/11 13:231AB004A0051001A0.151
A01999122017/2/11 13:231AB005A0051004D2006
A01999122017/2/11 13:231AB0016A0191006F501
A01999122017/2/11 13:231AB0017A0191007G24.52
  • 运用多表关联后结果比较
-- 2、利用join把两个表关联起来,注意在查询时仅取A005和A019做示范,所以需要用where语句做限制
select *
from db_order.sn_order_20210412 t1
join db_order.sn_orderitem_20210412 t2 -- on t2.order_id = t1.id       /*不带on展示的是做笛卡尔积后的结果*/
where t1.id in ('A005','A019')
and t2.order_id in ('A005','A019');   /*因为没有通过on关联,所以两个表都需要进行where限制*/
代码结果:join的原理是把两表做笛卡尔积
订单号订单金额会员号创建时间订单状态订单商品ID订单号商品ID商品名称商品价格商品数量
A0051200.1552017/1/1 13:232AB004A0051001A0.151
A0051200.1552017/1/1 13:232AB005A0051004D2006
A0051200.1552017/1/1 13:232AB0016A0191006F501
A0051200.1552017/1/1 13:232AB0017A0191007G24.52
A01999122017/2/11 13:231AB004A0051001A0.151
A01999122017/2/11 13:231AB005A0051004D2006
A01999122017/2/11 13:231AB0016A0191006F501
A01999122017/2/11 13:231AB0017A0191007G24.52
  •  通过on关联相同意义的字段
-- 3、join on 后的结果
select *
from db_order.sn_order_20210412 t1
join db_order.sn_orderitem_20210412 t2 on t2.order_id = t1.id 
where t1.id in ('A005','A019')
-- and t2.order_id in ('A005','A019');    /*相同意义的字段通过on关联后where只需要限制一个表里的条件就可以了*/
join on
订单号订单金额会员号创建时间订单状态订单商品ID订单号商品ID商品名称商品价格商品数量手动计算实际订单金额
A0051200.1552017/1/1 13:232AB004A0051001A0.1510.151200.15
A0051200.1552017/1/1 13:232AB005A0051004D20061200
A01999122017/2/11 13:231AB0016A0191006F5015099
A01999122017/2/11 13:231AB0017A0191007G24.5249
  •  导向结果——取A005和A019的会员号,统计A005和A019的累计订单金额,订单数,商品数
-- 统计A005和A019的累计订单金额,订单数,商品数
select t1.id 
      ,t1.member_id 
      ,sum(t1.order_money) as money 
      ,count(t1.id) as order_num
      ,sum(t2.item_num) as item_num 
from db_order.sn_order_20210412 t1
join db_order.sn_orderitem_20210412 t2 on t2.order_id = t1.id 
where t1.id in ('A005','A019')
-- and t2.order_id in ('A005','A019')
group by t1.member_id ;
汇总统计
订单号会员号订单金额订单数量商品数量实际手动计算订单金额
A00552400.3271200.15
A019121982399

对比上表:发现订单金额查询出现逻辑错误,和实际计算的有偏差——没有语法错误,但是逻辑错误!

思考:

  • 订单号是不是要去重
  • 订单金额不能用原来的计算,即不能简单的用汇总函数sum(t1.order_money)直接进行汇总,这是对关联后的表进行数据统计,故会与实际结果不相符
  • 是不是应该用另外一张表中的订单商品数量*商品价格计算订单金额—sum(t2.price*t2.item_num)
-- 5、修改逻辑错误
select t1.id 
      ,t1.member_id 
      ,sum(t2.price*t2.item_num) as money        /*修改逻辑错误*/
      ,count(distinct t1.id) as order_num        /*去重*/
      ,sum(t2.item_num) as item_num 
from db_order.sn_order_20210412 t1
join db_order.sn_orderitem_20210412 t2 on t2.order_id = t1.id 
where t1.id in ('A005','A019')
group by t1.member_id ;
修改逻辑错误后的结果
订单号会员号订单金额订单数量商品数量
A00551200.1517
A019129913

总结一些注意事项:

  1. 如果没有on,只有join:把订单表中的每一行,都与订单明细表中每一行匹配
  2. 如果加上on,表示在关联的时候只取能够匹配上的,也就是相同的记录;如果不相同的记录,就会不生成;【把不匹配的行不显示】
  3. where作用:是把where满足条件的记录先筛选出来,再与另一张关联;如果不加where过滤条件,如果都匹配上,也相当于生成一个M*N行的相似数据量数据;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值