【问题标题】:Need an array of date blocks from MySql Database需要来自 MySql 数据库的日期块数组
【发布时间】:2012-01-24 10:35:25
【问题描述】:

好的,我有一个包含 StartDate 和 EndDate 的行的数据库表。我需要做的是从中返回消耗的时间块。

所以,例如,如果我有 3 行如下:

RowID  StartDate   EndDate
1      2011-01-01  2011-02-01
2      2011-01-30  2011-02-20
3      2011-03-01  2011-04-01

那么使用的时间块如下:

2011-01-01 至 2011-02-20 和 2011-03-01 至 2011-04-01

有没有一种从 MySql 数据库中提取它的简单方法?欢迎提出任何建议!

【问题讨论】:

  • 我建议您使用任何运行 SQL 查询的语言来执行此操作。数据库级别的这种处理级别通常不是一个好主意 - 不是数据库应该做的。
  • 如果我正确理解了您的问题,那么您应该可以使用 DATEDIFF 函数来做到这一点

标签: mysql sql gaps-and-islands


【解决方案1】:

看下图,它代表了一些重叠的时间段

X----|              |--------|         |------X
    |-------X      X------------X
                         |----|     X----|

标有X 的任何连续时间段的开始或结束不属于任何其他时间段。如果我们确定这些时间,我们可以取得一些进展。

此查询标识边界。

SELECT boundary FROM
(

-- find all the lower bounds
    SELECT d1.StartDate AS boundary, 'lower' as type
    FROM dates d1
    LEFT JOIN dates d2 ON ( 
        d1.StartDate > d2.StartDate
        AND 
        d1.StartDate < d2.EndDate
    )
    WHERE d2.RowId IS NULL
    GROUP BY d1.StartDate

UNION

-- find all the upper bounds
    SELECT d1.EndDate AS boundary, 'upper' as type
    FROM dates d1
    LEFT JOIN dates d2 ON ( 
        d1.EndDate > d2.StartDate
        AND 
        d1.EndDate < d2.EndDate 
    )
    WHERE d2.RowId IS NULL
    GROUP BY d1.StartDate
) as boundaries

ORDER BY boundary ASC

对你的数据的查询结果是

boundry    | type
------------------
2011-01-01 | lower
2011-02-20 | upper
2011-03-01 | lower
2011-04-01 | upper

您所追求的日期范围在上面显示的连续上下限之间。通过一些后期处理,很容易找到这些。

【讨论】:

  • 谢谢各位,找到了解决办法!如前所述,我是在 PHP 而不是 MYSQL 中完成的。
【解决方案2】:

你试过mysql group concat吗

http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat

它会返回一个逗号分隔的字符串,但您仍然需要在应用程序中将其初始化为一个数组。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-02
    • 1970-01-01
    • 2016-03-10
    • 2010-11-10
    • 2016-02-05
    相关资源
    最近更新 更多