我目前有一个查询正在获取他们的deadline
距离不到3个月的记录。 deadline
存储为日期,但年份并不重要,因为此记录应每年标记。
我的查询:
SELECT client_name
FROM client
WHERE MOD(DAYOFYEAR(deadline) - DAYOFYEAR(CURDATE()), +365) <= 90
AND DAYOFYEAR(deadline) > DAYOFYEAR(CURDATE())
道歉,如果我从内存中写这个语法时出现错误 - 但它确实有效。
直到deadline
在第一季度,当前日期在最后一个季度,然后它不再返回记录。我该如何解决这个问题?
因此查询需要返回截止日期在当前日期3个月内的记录。 deadline
日期中的年份应该被忽略,因为这可能是几年前,但它是deadline
的重要日期和月份。
或者问题是我存储的日期?我应该每年更新一次吗?
由于
答案 0 :(得分:2)
一种方法是使用这样的条件测试:
WHERE CONCAT(YEAR(NOW()),DATE_FORMAT(d.deadline,'-%m-%d'))
+ INTERVAL CONCAT(YEAR(NOW()),DATE_FORMAT(d.deadline,'-%m-%d'))<NOW() YEAR
< NOW() + INTERVAL 3 MONTH
我们可以解开一点点。在第一行,我们正在创建一个&#34; next due&#34;截止日期,取当前年份,并附加deadline
的月和日值。
但是存在问题。其中一些&#34; next due&#34;截止日期是过去的。因此,为了解决这个问题(当3个月期间&#34;包装&#34;到下一年),我们需要为任何&#34; next due&#34;添加一年。在当前日期之前的截止日期。
现在,我们可以将其与3个月后的日期进行比较,以确定&#34; next due&#34;截止日期是在接下来的3个月内。
这有点复杂。
这里是一个SQL小提琴作为演示:http://sqlfiddle.com/#!2/c90e9/3。
对于测试,NOW()
不方便,因为它总是返回今天的日期。因此,为了进行测试,我们将所有出现的NOW()
替换为用户定义的变量 @now
,并将其设置为不同的日期,以便我们进行适当的测试。
这是我用于测试的SQL语句。第一个表达式是我们计划在WHERE
子句中使用的条件测试。为了进行测试,我们希望返回所有行,只看到哪些行due_in_3mo
标记为TRUE
(1
),哪些行标记为FALSE
({{1 }})。
SELECT列表中的第二个表达式只是&#34; next due&#34;截止日期,与第一个表达式中使用的截止日期相同。
其余的表达方式非常明显......我们还希望显示未来3个月的日期,我们将比较原始的&#34;截止日期&#34;日期值。
0
在内联视图中更改分配给SELECT
CONCAT(YEAR(@now),DATE_FORMAT(d.deadline,'-%m-%d'))
+ INTERVAL CONCAT(YEAR(@now),DATE_FORMAT(d.deadline,'-%m-%d'))<@now YEAR
< @now + INTERVAL 3 MONTH
AS `due_in_3mo`
, CONCAT(YEAR(@now),DATE_FORMAT(d.deadline,'-%m-%d'))
+ INTERVAL CONCAT(YEAR(@now),DATE_FORMAT(d.deadline,'-%m-%d'))<@now YEAR
AS `next_due`
, d.id
, d.deadline + INTERVAL 0 DAY AS `deadline`
, @now + INTERVAL 3 MONTH AS `now+3mo`
, @now + INTERVAL 0 DAY AS `now`
FROM d d
CROSS
JOIN (SELECT @now := '2015-11-01') i
ORDER BY d.id
的值(别名为@now
),以测试其他日期值。
(您可能希望使用i
代替DATE(NOW())
,以便时间不会混入,您可能希望从中减去另一天,这实际上取决于如何你想要处理NOW()
的边缘情况,其中月份和日期与当前日期相同。(即你想要处理那个&#34;在过去&#34或不。)
总结方法:生成&#34; next due&#34;截止日期为未来的DATE值,并与之后3个月的日期进行比较。