简体   繁体   English

选择不在其中一个日期范围内的所有日期

[英]Select all dates which are not in one of the date ranges

I have a table of time periods.我有一个时间段表。 (date ranges). (日期范围)。 These date ranges can overlap.这些日期范围可以重叠。 These date ranges can also be subranges of another data record.这些日期范围也可以是另一个数据记录的子范围。

+----+------------+------------+
| id | start_date | end_date   |
+----+------------+------------+
|  1 | 2019-01-01 | 2019-01-31 |
|  2 | 2019-02-01 | 2010-02-28 |
|  3 | 2019-04-01 | 2010-04-30 |
+----+------------+------------+

Then I have a table with invoices with invoice date and invoice number:然后我有一张带有发票日期和发票编号的发票表:

+----+--------------+------------+
| id | invoice_date | invoice_no |
+----+--------------+------------+
|  1 | 2019-01-14   | 4534534BG  |
|  2 | 2019-03-01   | 678678AAA  |
|  3 | 2019-04-13   | 123123DDD  |
+----+--------------+------------+

I'm looking for all invoices that are available in one date period.我正在寻找在一个日期期间可用的所有发票。

The goal in this small example would be to find the invoice from March: invoice_no: 678678AAA这个小例子的目标是找到三月份的发票:invoice_no: 678678AAA


My Approach我的方法

SELECT *
FROM `invoice`
WHERE (invoice_date BETWEEN '2019-01-01' AND '2019-01-31')

With this solution I would have to mark the found invoices (which provide a result) as "found" and then repeat the query for all other ranges.使用此解决方案,我必须将找到的发票(提供结果)标记为“找到”,然后对所有其他范围重复查询。 (Until no open invoices or periods are processed). (直到没有处理未清发票或期间)。 That would be a lot of queries, because there are a lot of invoices and a lot of time periods.那将是很多查询,因为有很多发票和很多时间段。 I would like to avoid that.我想避免这种情况。

Is there a trick here how to get the start and end date into the BETWEEN via Select?这里有一个技巧,如何通过选择将开始和结束日期输入到 BETWEEN 中?

To exhibit invoices that do not belong to any of the date ranges defined in the other table, you could use a not exists condition:要展示不属于另一个表中定义的任何日期范围的发票,您可以使用not exists条件:

select i.*
from invoices i
where not exists (
    select 1
    from periods p
    where i.invoice_date >= p.start_date and i.invoice_date <= p.end_date
)

Another typical solution is to use a left join antipattern, ie:另一个典型的解决方案是使用left join反模式,即:

select i.*
from invoices i
left join periods p 
    on i.invoice_date >= p.start_date and i.invoice_date <= p.end_date
where p.id is null

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM