我有一堆带时间戳的行(使用'datetime‘数据类型)
我想选择时间戳在特定月份内的所有行。
该列已建立索引,因此我不能将MONTH(timestamp) =3,因为这将使该索引不可用。
如果我有年和月变量(在perl中),有没有一些可怕的SQL可以使用,比如:
timestamp BETWEEN DATE($year, $month, 0) AND DATE($year, $month, 31);
但是更好,真的有效吗?
发布于 2010-02-24 17:34:52
我实际上会同意你提出的想法;也许会有一点不同:
select *
from your_table
where date_field >= '2010-01-01'
and date_field < '2010-02-01'
(当然,由您决定如何正确使用$year
和$month
)
注意< '2010-02-01'
部分:如果您的日期包含时间,则可能需要考虑这一点。
例如,如果您有一行日期类似于'2010-01-31 12:53:12'
的行,那么您可能希望选中该行--默认情况下,'2010-01-31'
表示'2010-01-31 00:00:00'
。
也许这看起来并不“好”;但它会起作用的;并使用索引...当我遇到这样的问题时,这是我通常使用的解决方案。
发布于 2010-02-24 22:27:03
这实际上是Pascal MARTIN的answer,但避免了必须显式地知道下一年/月是什么(所以当$month == 12
时,您不必递增年份和绕过$month
):
my $sth = $mysql_dbh->prepare(<<__EOSQL);
SELECT ...
FROM tbl
WHERE ts >= ? AND ts < (? + INTERVAL 1 MONTH)
__EOSQL
my $yyyymm = $year . '-' . sprintf('%02d', $month);
$sth->execute($yyyymm, $yyyymm);
为了获得额外的积分,你也可以这样做:
... WHERE ts BETWEEN ? AND (? + INTERVAL 1 MONTH - INTERVAL 1 SECOND)
该- INTERVAL 1 SECOND
将强制将日期的上限设置为日期时间/时间戳类型,设置为一天的最后一秒,正如Pascal所指出的,这是您想要的上限。
发布于 2010-02-24 17:36:19
如果您需要每年的同一个月,那么您所拥有的索引将不会对您有所帮助,任何SQL语法技巧都不会对您有所帮助
另一方面,如果您需要特定年份的月份,则任何具有日期范围的查询都应该可以做到这一点
https://stackoverflow.com/questions/2328051
复制相似问题