我正在尝试查找一个查询,该查询将为我提供范围在另一个范围内的天数。例如,假设有一个名为dates
的表 UID SmallRangeStart smallRangeEnd BigRangeStart BigRangeEnd
1 01 15 2016 01 20 2016 01 17 2016 02 30 2016
所以我想返回3,因为小范围在大范围内下降3天......是否有查询可以做到这一点?
答案 0 :(得分:1)
您要使用的逻辑是,如果两个范围完全不相交,则重叠为零。如果小范围开始和结束之前 BigRangeStart
或小范围开始并结束 BigRangeEnd
之后,就会发生这种情况。否则,如果确实发生了某些重叠,那么您希望区分SmallRangeStart
和BigRangeStart
的较大与较小之间的差异。 SmallRangeEnd
和BigRangeEnd
。
这是一个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;