使用MySQL查找日期范围之间的差距

时间:2014-01-31 22:28:46

标签: mysql sql

我在explainextended.com上发现了两个查询,这有助于我查看一系列日期范围并获得它们之间的差距(找到缺少的日期范围)。查询为thisthis。它们都有效,但最后一个适用于非重叠范围。这就是为什么我需要一种方法将两个查询合并为一个。我该怎么办?

示例数据

date        start           stop
2009.06.03  05:54:48:000    10:00:13:000
2009.06.03  09:26:45:000    09:59:40:000

分层数据

date        start           stop
2009.06.03  05:54:48:000    10:00:13:000

start                    end
NULL                     2009.06.03 05:54:48:000
2009.06.03 10:00:13:000  NULL

反转日期范围

SELECT  *
FROM    (
    SELECT  @startdate AS _startdate,
            (
            SELECT  enddate
            FROM    t_range rp
            WHERE   rp.startdate = _startdate
            ) AS e,
            @startdate := startdate AS s
    FROM    (
            SELECT  @startdate := CAST(NULL AS DATETIME)
            ) vars,
            t_range
    ORDER BY
            startdate
    ) q
UNION ALL
SELECT  @startdate AS _startdate,
    (
    SELECT  enddate
    FROM    t_range rp
    WHERE   rp.startdate = _startdate
    ),
    NULL

展平时间跨度

SELECT  MIN(s_start) AS r_start, MAX(s_stop) AS r_stop
FROM    (
    SELECT  s_start,
            s_stop,
            @r := @r + (s_start > @edate) AS r_num,
            @edate := GREATEST(@edate, s_stop)
    FROM    (
            SELECT  @r := 0,
                    @edate := '0001-01-01'
            ) vars,
            t_span
    ORDER BY
            s_start
    ) q
GROUP BY
    r_num

链接到示例sqlFiddle

http://sqlfiddle.com/#!2/fd1d2/7

我的测试查询

SELECT  *
FROM    (   
    SELECT  @startdate AS _startdate,
            (
            SELECT  s_end
            FROM    (
                SELECT  MIN(s_start) AS s_start, MAX(s_end) AS s_end
                FROM    (
                    SELECT  s_start,
                    s_end,
                    @r := @r + (s_start > @edate) AS r_num,
                    @edate := GREATEST(@edate, s_end)
                    FROM    (
                        SELECT  @r := 0,
                        @edate := '0001-01-01'
                    ) vars,
                    t_span
                    ORDER BY
                    s_start
                ) q
                GROUP BY
                r_num                   
            ) rp
            WHERE   rp.s_start = _startdate
            ) AS e,
            @startdate := s_start AS s
    FROM    (
            SELECT  @startdate := CAST(NULL AS DATETIME)
            ) vars,
            (
                SELECT  MIN(s_start) AS s_start, MAX(s_end) AS s_end
                FROM    (
                    SELECT  s_start,
                    s_end,
                    @r := @r + (s_start > @edate) AS r_num,
                    @edate := GREATEST(@edate, s_end)
                    FROM    (
                        SELECT  @r := 0,
                        @edate := '0001-01-01'
                    ) vars,
                    t_span
                    ORDER BY
                    s_start
                ) q
                GROUP BY
                r_num       
            ) test
    ORDER BY
            s_start
    ) q
UNION ALL
SELECT  @startdate AS _startdate,
    (
    SELECT  s_end
    FROM    t_span rp
    WHERE   rp.s_start = _startdate
    ),
    NULL        

0 个答案:

没有答案