如何使用SQL查找范围在另一个范围内的天数

时间:2016-10-21 05:01:44

标签: sql range

我正在尝试查找一个查询,该查询将为我提供范围在另一个范围内的天数。例如,假设有一个名为dates

的表
     UID    SmallRangeStart    smallRangeEnd     BigRangeStart     BigRangeEnd
       1     01 15 2016       01 20 2016        01 17 2016          02 30 2016

所以我想返回3,因为小范围在大范围内下降3天......是否有查询可以做到这一点?

3 个答案:

答案 0 :(得分:1)

您要使用的逻辑是,如果两个范围完全不相交,则重叠为零。如果小范围开始和结束之前 BigRangeStart或小范围开始并结束 BigRangeEnd之后,就会发生这种情况。否则,如果确实发生了某些重叠,那么您希望区分SmallRangeStartBigRangeStart较大较小之间的差异。 SmallRangeEndBigRangeEnd

这是一个MySQL解决方案:

SELECT CASE WHEN SmallRangeEnd < BigRangeStart THEN 0
            WHEN SmallRangeStart > BigRangeEnd THEN 0
            ELSE DATEDIFF(GREATEST(SmallRangeStart, BigRangeStart),
                          LEAST(SmallRangeEnd, BigRangeEnd))
       END AS days_in_range
FROM yourTable

移动到SQL Server时,查询也没有太大变化:

SELECT CASE WHEN SmallRangeEnd < BigRangeStart THEN 0
            WHEN SmallRangeStart > BigRangeEnd THEN 0
            ELSE DATEDIFF(day,
                          CASE WHEN SmallRangeStart > BigRangeStart
                               THEN SmallRangeStart ELSE BigRangeStart END,
                          CASE WHEN SmallRangeEnd < BigRangeEnd
                               THEN SmallRangeEnd ELSE BigRangeEnd END)
       END AS days_in_range
FROM yourTable

答案 1 :(得分:0)

对于mysql数据库,您可以使用datediff函数

     select datediff('2016-09-15','2016-09-12')

此查询将返回3

对于MSSQL数据库,你可以使用(只是减法)

   SELECT DATEDIFF(day,'2007-05-06 12:10:09','2007-05-07 12:10:09')

它将返回1

对于oracle,您可以使用

SELECT TO_DATE('2000-01-02', 'YYYY-MM-DD') -  
   TO_DATE('2000-01-01', 'YYYY-MM-DD') AS DateDiff

FROM dual

对于PostgreSQL:你可以使用

 SELECT DATE_PART('day', '2011-12-31 01:00:00'::timestamp - '2011-12-29  23:00:00'::timestamp);

- 它会返回:1

答案 2 :(得分:0)

这非常适合Postgres&#39;范围类型:

假设您在一行中有四列,首先使用:

计算两个范围的交集
daterange(smallrangestart, smallrangeend) * daterange(bigrangestart, bigrangeend) as overlap

这给出了两个范围的重叠。从新范围中,您只需从上限

中减去下限

上(重叠) - 下(重叠);

所以整个陈述是:

select upper(daterange(smallrangestart, smallrangeend) * daterange(bigrangestart, bigrangeend)) - 
       lower(daterange(smallrangestart, smallrangeend) * daterange(bigrangestart, bigrangeend))
from the_table
where uid = 1;