如果日期与年份无关,那么最佳(最快)的比较方法是什么?
表"日期":
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,但是我无法更改我在查询中添加的日期格式,因为该值通常来自另一个表(它是使用连接的更复杂查询的一部分)。
答案 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))
为了提高性能,您应该确保有一个包含since
和upto
字段的索引。
答案 3 :(得分:0)
在简短的Google-look和stackoverlook之后,我遇到了以下2个问题:
since
和upto
)可以属于不同的年份,这使得使用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)