我有一个时间表。 (日期范围)。这些日期范围可以重叠。这些日期范围也可以是另一个数据记录的子范围。
+----+------------+------------+
| 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 |
+----+------------+------------+
然后我有一张带有发票的表格,发票上有发票日期和发票编号:
+----+--------------+------------+
| id | invoice_date | invoice_no |
+----+--------------+------------+
| 1 | 2019-01-14 | 4534534BG |
| 2 | 2019-03-01 | 678678AAA |
| 3 | 2019-04-13 | 123123DDD |
+----+--------------+------------+
我正在寻找一个日期范围内可用的所有发票。
此小示例中的目标是查找3月份的发票:invoice_no:678678AAA
我的方法
SELECT *
FROM `invoice`
WHERE (invoice_date BETWEEN '2019-01-01' AND '2019-01-31')
使用此解决方案,我必须将找到的发票(提供结果)标记为“找到”,然后对所有其他范围重复查询。 (直到未处理未结发票或期间为止)。那将是很多查询,因为有很多发票和很多时间段。我想避免这种情况。
这里有一个技巧,如何通过Select将开始日期和结束日期输入到BETWEEN中?
要显示不属于另一个表中定义的任何日期范围的发票,可以使用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
)
另一个典型的解决方案是使用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