日期之间的日期,忽略年份

时间:2014-09-01 00:23:59

标签: mysql date between

如果日期与年份无关,那么最佳(最快)的比较方法是什么?

表"日期":

    some_column| since        | upto        |  
    -----------|--------------|-------------|
   'foo'       | '2011-05-01' | '2013-06-01'|

现在我想让这个查询返回' foo'

SELECT foo FROM dates WHERE '2014-05-05' BETWEEN `since` AND `upto`

如果需要,我可以在"日期"中更改存储日期的类型/格式table,但是我无法更改我在查询中添加的日期格式,因为该值通常来自另一个表(它是使用连接的更复杂查询的一部分)。

5 个答案:

答案 0 :(得分:3)

使用DayOfYear功能:

 SELECT foo FROM dates WHERE DayOfYear('2014-05-05') 
    BETWEEN DayOfYear(`since`) AND DayOfYear(`upto`)

答案 1 :(得分:2)

SELECT foo FROM dates WHERE DATE_FORMAT('2014-01-15', "%m-%d") 
    BETWEEN DATE_FORMAT(`since`,"%m-%d") AND DATE_FORMAT(`upto`,"%m-%d")

这是SQL FIDDLE演示

答案 2 :(得分:1)

由于您表示可以在数据中存储任意年份,因此您可以继续使用DATE类型。然后它归结为如何查询。

  • 使用固定的任意年份存储字段。您应该使用闰年来适应2月29日值的可能性。 2000年效果很好。 (0004将无效,因为它对于MySQL的Date类型来说太小了。)

  • 替换您在同一年查询的任何值的年份。

  • 考虑跨越一年末和下一年的范围。要完全回答这个问题,您需要查询如下:

    SET @dt = cast(CONCAT('2000',RIGHT(thesourcedatevalue,6)) as DATE);
    
    SELECT some_column FROM dates
    WHERE (since <= upto AND since <= @dt AND upto >= @dt) OR
          (since > upto AND (since <= @dt OR upto >= @dt))
    

    Here is a SQL Fiddle that demonstrates

  • 为了提高性能,您应该确保有一个包含sinceupto字段的索引。

答案 3 :(得分:0)

在简短的Google-look和stackoverlook之后,我遇到了以下2个问题:

  • 一年多了1天(2月29日)
  • 要求的范围(sinceupto)可以属于不同的年份,这使得使用DayOfYear()成为一个问题。这是我想出的SQL查询。

比方说我们要检查日期“ 2014-05-05”:

SELECT foo FROM `dates` WHERE
        (
    /*     --------    since and upto are from same year    --------    */
            YEAR(`since`) = YEAR(`date_fin`)
            AND (
                (
                    MONTH(`since`) < "05"
                    OR
                    (
                        MONTH(`since`) = "05"
                        AND
                        DAY(`since`) <= "05"
                    )
                ) AND (
                    MONTH(`date_fin`) < "05"
                    OR
                    (
                        MONTH(`date_fin`) = "05"
                        AND
                        DAY(`date_fin`) >= "05"
                    )
                )
            )
        )OR(
    /*     --------    since and upto are from different year    --------    */
            YEAR(`since`) <> YEAR(`date_fin`) AND (
                (
                    MONTH(`since`) < "05"
                    OR
                    (
                        MONTH(`since`) = "05"
                        AND
                        DAY(`since`) <= "05"
                    )
                ) OR (
                    MONTH(`date_fin`) > "05"
                    OR
                    (
                        MONTH(`date_fin`) = "05"
                        AND
                        DAY(`date_fin`) >= "05"
                    )
                )
            )
        )

答案 4 :(得分:0)

我通过以下方式解决了类似的问题:

SELECT foo FROM dates

WHERE   '0000-05-05'
BETWEEN SUBDATE(since, INTERVAL YEAR(since) YEAR)
AND     SUBDATE(upto, INTERVAL YEAR(since) YEAR)

OR      ADDDATE('0000-05-05', INTERVAL 1 YEAR)
BETWEEN SUBDATE(since, INTERVAL YEAR(since) YEAR)
AND     SUBDATE(upto, INTERVAL YEAR(since) YEAR)

首先,我们将所有日期重置为零,接下来我们要寻找两个范围之间的特定日期(也重置为零)。在后面的例子中,我们已经从外部源传递了“重置”日期,但这也可以在 mysql 中完成:

WHERE   SUBDATE('2014-05-05', INTERVAL YEAR('2014-05-05') YEAR)