Date between dates, ignore year

橙三吉。 提交于 2019-12-23 07:28:36

问题


What's the best (fastest) approach to compare if date is in range of dates independently from year?

table "dates":

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

Now I want this query to return 'foo'

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

If needed, I can change type/format of stored dates in "dates" table, but I cannot change format of date which I put into query as that value is typically from another table (It's part of more complex query using joins).


回答1:


Use the DayOfYear function:

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



回答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")

Here's the SQL FIDDLE demo




回答3:


Since you indicated that you're fine storing an arbitrary year in your data, then you can keep using a DATE type. Then it just comes down to how to query.

  • Store the fields using a fixed arbitrary year. You should use a leap-year to accommodate the possibility of Feb 29th values. Year 2000 works nicely. (0004 won't work because it's too small for MySQL's Date type.)

  • Replace the year of any value you're querying with the same year.

  • Consider ranges that cross over the end of one year and into the next. To fully answer that, you'll need a query such as the following:

    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

  • For performance, you should be sure that there is an index that includes the since and upto fields.




回答4:


After a brief google-look and stackoverlook, I came across theses 2 problems :

  • some year has 1 day more (29th of feb)
  • the range asked (since and upto) can belong to different years, making use of DayOfYear() a problem. This is the sql query I came up with.

Let's say we have a date '2014-05-05' to check :

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"
                    )
                )
            )
        )


来源:https://stackoverflow.com/questions/25597491/date-between-dates-ignore-year

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!