【问题标题】:Select all dates which are not in one of the date ranges选择不在某一日期范围内的所有日期
【发布时间】:2020-04-01 19:17:10
【问题描述】:

我有一个时间段表。 (日期范围)。这些日期范围可以重叠。这些日期范围也可以是另一个数据记录的子范围。

+----+------------+------------+
| 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 中吗?

【问题讨论】:

    标签: mysql sql date select where-clause


    【解决方案1】:

    要展示不属于其他表中定义的任何日期范围的发票,您可以使用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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-02
      相关资源
      最近更新 更多