首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >select * from table where datetime in month (不破坏索引)

select * from table where datetime in month (不破坏索引)
EN

Stack Overflow用户
提问于 2010-02-25 01:29:52
回答 5查看 6.6K关注 0票数 5

我有一堆带时间戳的行(使用'datetime‘数据类型)

我想选择时间戳在特定月份内的所有行。

该列已建立索引,因此我不能将MONTH(timestamp) =3,因为这将使该索引不可用。

如果我有年和月变量(在perl中),有没有一些可怕的SQL可以使用,比如:

代码语言:javascript
运行
复制
timestamp BETWEEN DATE($year, $month, 0) AND DATE($year, $month, 31);

但是更好,真的有效吗?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-02-25 01:34:52

我实际上会同意你提出的想法;也许会有一点不同:

代码语言:javascript
运行
复制
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'

也许这看起来并不“好”;但它会起作用的;并使用索引...当我遇到这样的问题时,这是我通常使用的解决方案。

票数 11
EN

Stack Overflow用户

发布于 2010-02-25 06:27:03

这实际上是Pascal MARTIN的answer,但避免了必须显式地知道下一年/月是什么(所以当$month == 12时,您不必递增年份和绕过$month ):

代码语言:javascript
运行
复制
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);

为了获得额外的积分,你也可以这样做:

代码语言:javascript
运行
复制
... WHERE ts BETWEEN ? AND (? + INTERVAL 1 MONTH - INTERVAL 1 SECOND)

- INTERVAL 1 SECOND将强制将日期的上限设置为日期时间/时间戳类型,设置为一天的最后一秒,正如Pascal所指出的,这是您想要的上限。

票数 2
EN

Stack Overflow用户

发布于 2010-02-25 01:36:19

如果您需要每年的同一个月,那么您所拥有的索引将不会对您有所帮助,任何SQL语法技巧都不会对您有所帮助

另一方面,如果您需要特定年份的月份,则任何具有日期范围的查询都应该可以做到这一点

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2328051

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档