sql解决两店在时间段范围内售卖情况的问题

一、问题:

在这里插入图片描述
简单形象的比喻来说,比如,一斤苹果,在张三那卖,只有在表1的对应时间范围有卖,且对应的是价格1,然后在李四那卖,只有在表2的对应时间有卖,对应的是价格2,然后我想知道在李四有卖的时候,张三也有卖的情况下价格分别是多少?我想考虑哪个比较便宜,这里的时间就是包含关系。
*

二、分析

上面的问题就是对比价格的问题,表一存在就是zhangshan售卖表,表二存在就是李四的售卖情况表,两表售卖的东西都为同一种,表结构如下:
在这里插入图片描述
这时可以忽略货物的名称啥啥啥的,只用考虑zhangshan在售卖时间段内lisi是否在正常售卖,售卖就列出其价格和售卖时间
,lisi在售卖时间段zhangshan是否在售卖,如果在就对比价格,不在的话就列为空。
注意,此时两表存在的关联关系可以用笛卡尔积和以zhangsan表和lisi表为驱动查询对应的数据,再根据时间查询符合要求的数据!说干就干!

三、开始写加入测试数据,写sql

zhangsan表添加数据

INSERT INTO  `shop_zhangsan`(`start_time`, `finish_time`, `current_price`, `id`) VALUES ('2022-09-04', '2022-09-09', 14.00, 1);
INSERT INTO `shop_zhangsan`(`start_time`, `finish_time`, `current_price`, `id`) VALUES ('2022-09-18', '2022-09-19', 15.00, 2);

lisi表添加数据

INSERT INTO `shop_lisi`(`id`, `start_time`, `finish_time`, `current_price`) VALUES (1, '2022-09-03', '2022-09-10', 12.00);
INSERT INTO `shop_lisi`(`id`, `start_time`, `finish_time`, `current_price`) VALUES (2, '2022-09-12', '2022-09-15', 13.00);

开始写sql !(此处sql写法有很多,我就使用最通俗易懂的来做了)
注:未考虑数据量大产生的join buffer问题
1、先使用二者笛卡尔交际来找对应符合条件的数据

 SELECT
	a.start_time AS lisi_st,
	a.finish_time AS lisi_ft,
	a.current_price AS lisi_cp,
	b.start_time AS zhangshan_st,
	b.finish_time AS zhangshan_ft,
	b.current_price AS zhangshan_cp 
FROM
	shop_lisi a, shop_zhangsan b   
	where a.start_time < b.start_time AND a.finish_time > b.finish_time 
	 or (a.start_time > b.start_time AND a.finish_time< b.finish_time)

结论 可以看出符合上述条件的数据就只有一条,不能直观的看出两者的售卖时间价格对比
在这里插入图片描述
2、使用关联查询筛选出对应条件的数据
常见的关联方式在mysql一般有三种,分别是join,left join,right join

还有两种分别取两表不相关的连接,有兴趣的小伙伴可以自行百度
a left join b on b.id is null 
a right join b on a.id is null 

我们此时想到的就是最简单的left join方式,以左表为驱动,查询关联数据,即是 a在售卖时间内b是否在售卖,价格如何,
同理,也可以以b表为驱动,查询a的情况(本人较懒,sql少改动就改成right join),两表取并集就是最终的数据了

下面是sql编写

SELECT
	a.start_time AS lisi_st,
	a.finish_time AS lisi_ft,
	a.current_price AS lisi_cp,
	b.start_time AS zhangshan_st,
	b.finish_time AS zhangshan_ft,
	b.current_price AS zhangshan_cp 
FROM
	shop_lisi a
	LEFT JOIN shop_zhangsan b   on 
 a.start_time < b.start_time AND a.finish_time > b.finish_time 
UNION all
 SELECT
	a.start_time AS lisi_st,
	a.finish_time AS lisi_ft,
	a.current_price AS lisi_cp,
	b.start_time AS zhangshan_st,
	b.finish_time AS zhangshan_ft,
	b.current_price AS zhangshan_cp 
FROM
	shop_lisi a
	right JOIN shop_zhangsan b   on 
 a.start_time > b.start_time AND a.finish_time < b.finish_time

这里采用的 union all 也可以换成union,union all没有对结果集去重,减少了回表的时间,因为上面的数据基本不存在重复数据,此处采用的union 关联两个查询的结果集也是可以的,效率影响不大。
最后看看结果吧:
在这里插入图片描述
上述结果满足最终的要求了,很清晰的对比(上述sql有很大的优化空间,感兴趣可以自己尝试一下)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值