SQL left join 左表合并去重 并 合并重复列值

业务需求: 一款商品有几款不同类型的规格,不同用户不同时间下单后有相应的订单记录和派单记录,现需要查询需要派单的订单,规格相同的商品合并为一列。

select o.sn,
CONCAT(DATE_FORMAT(oi.travel_start,'%Y-%m-%d'),'至',(DATE_FORMAT(oi.travel_end,'%Y-%m-%d'))) as travelTime,
oi.travel_day as travelDay,oi.travel_end as travelEnd,oi.travel_start as travelStart,oi.goods_name,
o.camper_ids,o.client_type,o.flow_price,o.create_time as startDate,o.order_status,o.payment_method,o.payment_time,o.member_name,
o.store_name as store_name,o.store_id as store_id,o.order_type,
d.status as dispatchStatus
from li_order AS o
left join li_order_item as oi on o.sn = oi.order_sn
left join stu_dispatch as d on oi.goods_id = d.goods_id
where o.order_type = 'TRAVEL'
//  使用left join, A表与B表所显示的记录数为 1:1 或 1:0,A表的所有记录都会显示,
//   B表只显示符合条件的记录。但如果B表符合条件的记录数大于1条,就会出现1:n的情况,
//   这样left join后的结果,记录数会多于A表的记录数。

在这里插入图片描述
结果: 相同的订单重复出现。问题出现的原因:
MySQL left join 语句格式为: A LEFT JOIN B ON 条件表达式
left join 是以A表为基础,A表即左表,B表即右表。
左表(A)的记录会全部显示,而右表(B)只会显示符合条件表达式的记录,如果在右表(B)中没有符合条件的记录,则记录不足的地方为NULL。
解决方法: 使用非唯一标识的字段做关联,使A表与B表所显示的记录数为 1:1对应关系。

select DISTINCT(o.sn),
CONCAT(DATE_FORMAT(oi.travel_start,'%Y-%m-%d'),'至',(DATE_FORMAT(oi.travel_end,'%Y-%m-%d'))) as travelTime,
oi.travel_day as travelDay,oi.travel_end as travelEnd,oi.travel_start as travelStart,oi.goods_name,
o.camper_ids,o.client_type,o.flow_price,o.create_time as startDate,o.order_status,o.payment_method,o.payment_time,o.member_name,
o.store_name as store_name,o.store_id as store_id,o.order_type,
d.status as dispatchStatus
from li_order AS o
left join li_order_item as oi on o.sn = oi.order_sn
left join stu_dispatch as d on oi.goods_id = d.goods_id
where o.order_type = 'TRAVEL'
//  DISTINCT 用于返回唯一不同的值。

在这里插入图片描述
结果: 不同的订单不重复出现。 DISTINCT查询结果是:第一个表唯一的数据,重复的结果没显示出来。但是不符合业务需求,业务要求是同一规格的商品的订单合并为一条显示,
解决方法: 根据一个或多个列对结果集进行分组,并将一列的多个值合并成一个。

select o.sn, GROUP_CONCAT(DISTINCT o.camper_ids),
CONCAT(DATE_FORMAT(oi.travel_start,'%Y-%m-%d'),'至',(DATE_FORMAT(oi.travel_end,'%Y-%m-%d'))) as travelTime,
oi.travel_day as travelDay,oi.travel_end as travelEnd,oi.travel_start as travelStart,oi.goods_name,
o.client_type,o.flow_price,o.create_time as startDate,o.order_status,o.payment_method,o.payment_time,o.member_name,
o.store_name as store_name,o.store_id as store_id,o.order_type,
d.status as dispatchStatus
from li_order AS o
left join li_order_item as oi on o.sn = oi.order_sn
left join stu_dispatch as d on oi.goods_id = d.goods_id
where o.order_type = 'TRAVEL'
GROUP BY oi.goods_name
//  GROUP BY 根据一个或多个列对结果集进行分组。
//  GROUP_CONCAT() 将分组中的字符串与各种选项进行连接,也就是将一列的多个值合并成一个。

在这里插入图片描述
结果: 接上面,业务要求是同一规格的商品的订单合并为一条显示后,还是不满足所有业务需要。 情况会有:同一款商品有两笔不同规格的订单,其中一笔订单已经派单成功了,按理就不能够再查出来。
解决方法: 对最终结果的显示再加一个条件。

select GROUP_CONCAT(DISTINCT d.group_orderItem_sn) as sn, GROUP_CONCAT(DISTINCT o.camper_ids) as camperIds, SUM(DISTINCT oi.num) as travelNumber,oi.goods_id,
oi.goods_name,CONCAT(DATE_FORMAT(oi.travel_start,'%Y-%m-%d'),'至',(DATE_FORMAT(oi.travel_end,'%Y-%m-%d'))) as travelTime,
oi.travel_day as travelDay,oi.travel_end as travelEnd,oi.travel_start as travelStart,o.client_type,o.flow_price,o.create_time as startDate,
o.order_status,o.payment_method,o.payment_time,o.member_name,o.store_name as store_name,o.store_id as store_id,o.order_type,d.status as dispatchStatus
from li_order AS o
left join li_order_item as oi on o.sn = oi.order_sn
left join stu_dispatch as d on o.sn = d.group_orderItem_sn
where o.order_type = 'TRAVEL'  and o.sn in (SELECT group_orderItem_sn from stu_dispatch where status = 'WAIT')
GROUP BY oi.goods_name

在这里插入图片描述

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值