背景
我有一张表Deliveries
:
+---------+-------------+---------------+
| courier | pickup_date | delivery_date |
+---------+-------------+---------------+
| Sebby | 2015-05-02 | 2015-05-04 |
| Ian | 2015-05-07 | 2015-05-08 |
| Sebby | 2015-05-12 | 2015-05-16 |
| Bart | 2015-05-18 | 2015-05-21 |
| Ian | 2015-05-27 | 2015-05-29 |
+---------+-------------+---------------+
视觉上,快递员的时间表如下:
问题
搜索条件是一个日期范围,我必须返回该日期范围内的“可用”快递。例如,搜索条件来自2015-05-16 - 2015-05-17
。查看表格或日历,很容易知道在这些日期只有Ian和Bart可用。 我如何在MySQL中执行此操作?
我尝试了什么
我看到了answer,所以我尝试了这样:
SELECT courier FROM Deliveries
WHERE pickup_date > '2015-05-17'
OR delivery_date < '2015-05-16'
这给了我伊恩和巴特。但它也包括Sebby。这是因为虽然Sebby的2015-05-12 - 2015-05-16
与搜索条件重叠,但2015-05-02 - 2015-05-04
不会在查询中返回。我需要做一些限制查询的事情。如果快递员的时间表重叠一次,则不要在查询中返回。我可以在源代码中执行此操作,但我更喜欢在MySQL中进行所有过滤。源代码将是最后的手段。
This突然出现了可能已有答案的问题,看起来与我之前的尝试相似。
This question(以及答案)也谈到了我之前的尝试。我看到的其他所有内容似乎都是这样或那样的,但却没有回答我的问题。
我是否在正确的轨道上?或者我对这个问题的处理方法是错误的?
模式
我将提供脚本来创建表以节省您的时间:)
CREATE TABLE Deliveries (
courier varchar(15),
pickup_date date,
delivery_date date
);
INSERT INTO Deliveries (courier, pickup_date, delivery_date) VALUES
('Sebby', '2015-05-02', '2015-05-04'),
('Ian', '2015-05-07', '2015-05-08'),
('Sebby', '2015-05-12', '2015-05-16'),
('Bart', '2015-05-18', '2015-05-21'),
('Ian', '2015-05-27', '2015-05-29');
答案 0 :(得分:2)
这样的事可能适合你。我还建议你有另一张桌子,只为你的快递名字,让事情更加优化。
select distinct courier
from deliveries d
where not exists (
select 1 from deliveries d2
where d.courier = d2.courier
and (('2015-05-16' between pickup_date and delivery_date)
or ('2015-05-17' between pickup_date and delivery_date)
or (pickup_date between '2015-05-16' and '2015-05-17')
or (delivery_date between '2015-05-16' and '2015-05-17'))
)
通过使用where not exists
,这应该排除任何快递员:
我认为这涵盖了所有基础 - 最后两项中只有一项是绝对必要的,它涵盖了现有交付完全在搜索期内的情况
答案 1 :(得分:0)
您的查询与字符串到日期 - 时间转换有某种关系 -
由于您的数据库表字段似乎没有以datetime或日期格式存储内容 -
所以你的查询应该是这样的 -
sh
答案 2 :(得分:0)
你想知道在他忙碌的时候是否存在快递的一些行,并过滤掉那些快递员。这是为了确定您的日期范围是否与选择和交付日期重叠一些范围:
select distinct d1.courier from Delivers d1
where not exists(select * from Delivers d2
where d1.courier = d2.courier and
d2.pickDate <= '2015-05-17' and d2.deliveryDate >= '2015-05-16')
有2个间隔的9种可能情况。人们可以用不同的情况来评估谓词:
http://yetanothermathprogrammingconsultant.blogspot.com/2014/09/when-do-two-intervals-overlap.html
答案 3 :(得分:0)
以下查询将为您执行此操作,请查看fiddle
SELECT DISTINCT courier FROM Deliveries WHERE courier NOT IN (
SELECT courier
FROM Deliveries
WHERE (('2015-05-17' between pickup_date AND delivery_date)
OR ('2015-05-16' between pickup_date AND delivery_date))
);
修改强>
SELECT DISTINCT courier FROM Deliveries WHERE courier NOT IN (
SELECT courier
FROM Deliveries
WHERE (('2015-05-17' between pickup_date AND delivery_date)
OR ('2015-05-14' between pickup_date AND delivery_date))
OR ((pickup_date between '2015-05-14' AND '2015-05-17')
OR ( delivery_date between '2015-05-14' AND '2015-05-17'))
);