【发布时间】:2015-01-15 22:45:02
【问题描述】:
我有一个嵌入式查询,用于提取上个月的数据。直到本月(1 月)之前,一切都运行良好。我的代码如下所示:
(MONTH(CURRENT DATE)-1) = MONTH(TSTAMP)
我之所以这样设置,是因为我的数据中有一个时间戳,是查询的基础。这通常像一个魅力,但它在这个月不起作用,我认为这是因为新年。在处理不同的年份时,此功能如何工作?有没有办法将它写入查询,所以我不必担心年份的变化?
【问题讨论】:
我有一个嵌入式查询,用于提取上个月的数据。直到本月(1 月)之前,一切都运行良好。我的代码如下所示:
(MONTH(CURRENT DATE)-1) = MONTH(TSTAMP)
我之所以这样设置,是因为我的数据中有一个时间戳,是查询的基础。这通常像一个魅力,但它在这个月不起作用,我认为这是因为新年。在处理不同的年份时,此功能如何工作?有没有办法将它写入查询,所以我不必担心年份的变化?
【问题讨论】:
您可以使用年份来执行此操作,如下所示:
YEAR(CURRENT DATE) * 12 + MONTH(CURRENT DATE) - 1 = YEAR(TSTAMP) * 12 + MONTH(TSTAMP)
本质上,这将日期转换为自时间 0 以来的月份——因此 -1 有意义。
【讨论】:
执行此操作的正确方法是使用范围查询(也有一个with an exclusive upper-bound, <),这样如果有可用的索引,数据库就可以免费提供给我们。
每月的第一天可以通过以下方式轻松检索:
CURRENT_DATE - (DAY(CURRENT_DATE) - 1) DAYS
(减去当前日期和月初之间的天数差)
这为查询提供了一个很好的上限条件:
WHERE tStamp < CURRENT_DATE - (DAY(CURRENT_DATE) - 1) DAYS
(获取当月开始之前的所有内容)。
但是,由于我们真的只对上个月感兴趣,因此我们还需要限制下限。嗯,这就是那个月开始之后的一切……而且我们已经可以得到当前月的开始:
WHERE tStamp >= CURRENT_DATE - (DAY(CURRENT_DATE) - 1) DAYS + 1 MONTH
AND tStamp < CURRENT_DATE - (DAY(CURRENT_DATE) - 1) DAYS
calendarDate - DATE
year - INTEGER
month - INTEGER
dayOfMonth - INTEGER
...您可以使用此表来获取相关值:
WHERE tStamp >= (SELECT calendarDate
FROM calendarTable
WHERE year = YEAR(CURRENT_DATE - 1 MONTH)
AND month = MONTH(CURRENT_DATE - 1 MONTH)
AND dayOfMonth = 1)
AND tStamp < (SELECT calendarDate
FROM calendarTable
WHERE year = YEAR(CURRENT_DATE)
AND month = MONTH(CURRENT_DATE)
AND dayOfMonth = 1)
(这个有几种不同的形式,但这个看起来很简单)
【讨论】: