SQL:选择*其中start和end在两个日期之内

时间:2018-03-06 09:31:08

标签: mysql sql date between

我有一个tasks表:

+-------+-------------------+---------------------+---------------------+
| rowid | title             | start_task          | due_date            |
+-------+-------------------+---------------------+---------------------+
| 1     | Paint Apartment   | 2018-03-01 07:00:00 | 2018-03-16 15:00:00 |
+-------+-------------------+---------------------+---------------------+
| 2     | Meeting with John | 2018-03-10 10:00:00 | 2018-03-10 12:30:00 |
+-------+-------------------+---------------------+---------------------+
| 3     | Buy Milk          | 2018-03-04 20:00:00 | NULL                |
+-------+-------------------+---------------------+---------------------+
| 4     | Renew Rail Card   | NULL                | 2018-03-07 09:00:00 |
+-------+-------------------+---------------------+---------------------+

我想要选择2018-03-052018-03-11周的所有内容,以便打印第1,2和2行。 4。

所以我的查询应该包含以下内容:

  1. 2018-03-05和2018-03-11之间的所有内容
  2. 2018-03-05和2018-03-11之间到期的所有内容
  3. start_task和due_date期间在2018-03-05和2018-03-11之间的所有内容
  4. 我当前的SQL执行1和2并打印第2行和第2行4:

    SELECT * FROM `tasks` tasks where ((`start_task` >= '2018-03-05 00:00:00' and `start_task` <= '2018-03-11 23:59:59') OR (`due_date` >= '2018-03-05 00:00:00' and `due_date` <= '2018-03-11 23:59:59'))
    

3 个答案:

答案 0 :(得分:2)

您正在检查两个间隔(start_datedue_date和3月5日➔3月11日)之间的非空交叉点。

你可以这样做:

select *
  from `tasks` tasks
 where (`start_task` is null or `start_task` <= '2018-03-11 23:59:59') -- start <= end
   and (`due_date`   is null or `due_date`   >= '2018-03-05 00:00:00') -- end   >= start

(假设null开始/结束日期表示无限间隔)

记住它:&#34;每个间隔必须在另一个结束之前开始&#34;。

为了更好地理解原因,请考虑反问题。

为了使两个区间有一个空的交集,您必须在interval 2开始之前interval 1结束:

interval 1: --------(---)--------
interval 2: -(---)---------------

interval 2interval 1结束后开始:

interval 1: --------(---)--------
interval 2: ---------------(---)-

否定这两个条件的结合并应用De Morgan来获得非空交叉的条件。

答案 1 :(得分:1)

所以你只是错过了任何开始 - 到期日期超过你检查周的东西?这应该可以解决问题:

SELECT 
    * 
FROM 
    `tasks` tasks 
WHERE 
    (
        (`start_task` >= '2018-03-05 00:00:00' and `start_task` <= '2018-03-11 23:59:59') 
        OR (`due_date` >= '2018-03-05 00:00:00' and `due_date` <= '2018-03-11 23:59:59')
        OR (`start_task` <= '2018-03-11 23:59:59' and `due_date` >= '2018-03-05 00:00:00')
    )

如前所述,这也可以简化为单一测试:

SELECT 
    * 
FROM 
    `tasks` tasks 
WHERE
    COALESCE(`start_task`, '2018-03-11 23:59:59') <= '2018-03-11 23:59:59' 
    AND COALESCE(`due_date`, '2018-03-05 00:00:00') >= '2018-03-05 00:00:00'

我认为这是MySQL的正确语法,如果不是,请道歉。请注意,这也意味着当您可能希望失败时,NULL开始日期和NULL截止日期将成为过关?

答案 2 :(得分:-2)

您可以使用SQL between Operator

SELECT 
  * 
FROM 
  tasks
WHERE 
  start_task BETWEEN "2018-03-05" and "2018-03-11" 
  OR due_date BETWEEN "2018-03-05" and "2018-03-11"
  OR start_task <= "2018-03-05" and due_date>="2018-03-11";