Mysql SQL-日期介于(xxxx-06-21和xxxx-09-21)之间
如何使用MySQL中的BETWEEN函数来搜索任何年份中的日期,但是在特定的日期/月份到特定的日期/月份之间?或者,如果不能使用BETWEEN,我还能如何实现它 更具描述性的是,我正在尝试将季节性搜索添加到我的照片存档网站。因此,如果用户选择搜索“夏季”照片,它将搜索6月21日至9月21日期间拍摄的照片,但不包括任何一年的照片 如果嘉士伯制造了SQL,我想应该是:)Mysql SQL-日期介于(xxxx-06-21和xxxx-09-21)之间,mysql,sql,search,Mysql,Sql,Search,如何使用MySQL中的BETWEEN函数来搜索任何年份中的日期,但是在特定的日期/月份到特定的日期/月份之间?或者,如果不能使用BETWEEN,我还能如何实现它 更具描述性的是,我正在尝试将季节性搜索添加到我的照片存档网站。因此,如果用户选择搜索“夏季”照片,它将搜索6月21日至9月21日期间拍摄的照片,但不包括任何一年的照片 如果嘉士伯制造了SQL,我想应该是:) 非常感谢在MySQL中应该有一个与Oracle的to_date()函数等价的函数。我认为最简单的方法是获取日期,将其转换为字符串,
非常感谢在MySQL中应该有一个与Oracle的to_date()函数等价的函数。我认为最简单的方法是获取日期,将其转换为字符串,获取后缀,并在
之间运行它:
WHERE date.MONTH() || date.DAY() BETWEEN '0621' AND '0921'
您可以使用和函数分离日期:
where month(date_column) between 6 and 9
and if(month(date_column) = 6 and day(date_column) < 21, 0, 1)
and if(month(date_column) = 9 and day(date_column) > 21, 0, 1)
其中月份(日期列)介于6和9之间
如果(月(日期列)=6,天(日期列)<21,0,1)
如果(月(日期列)=9,天(日期列)>21,0,1)
这些东西之所以需要,是因为你的边界与月份不符
如果你打算做很多这类事情,那么最好预先计算完整日期的月日版本,以便对其进行索引。如果你真的需要这种格式的搜索,
我想最好把日期一栏一分为二
year int(4)unsigned
(哪一年)
month\u day int(4)unsigned
(即mmdd)
在月\日,年
,
这样做的目的是使索引工作得更好
类似查询的示例
where month_day between 621 and 921 -- make use on index
另一个例子
where year=2011 and month_day between 900 and 930 -- make use on index too
其他地方给出的解决方案,WHERE date.MONTH()| | date.DAY(),介于'0621'和'0921'
之间,是一个很好的解决方案(值得一试,因为它适用于大多数MySQL数据库),但我想指出,它(以及大多数涉及每行函数的查询)无法很好地扩展到大型表
当然,我的经验是MySQL不是经常用于大小会有很大差别的,但是,如果是的话,你也应该考虑下面的内容。
我们过去使用的一个技巧是将额外的列与insert/update触发器组合在一起,这样计算成本只在必要时发生(当数据更改时),而不是在每次选择时发生
由于绝大多数数据库的读取频率远远高于写入频率,因此这将分摊所有选择的成本
例如,添加一个名为MMDD
的新列CHAR(4)
,并在其上点击一个索引。然后在表上设置insert/update触发器,以便根据已提供的公式,date.MONTH()| | date.DAY()
,使用date
列设置新触发器
然后,在执行查询时,跳过每行函数,而是使用:
WHERE MMDD BETWEEN '0621' AND '0921'
事实上,它的索引将保持速度快得令人眼花缭乱,在插入/更新过程中只需一个触发器和一个额外的列
触发器的成本与此无关,因为它小于为每个select操作执行触发器的成本。列所需的额外存储是一个缺点,但是,如果检查人们对数据库提出的所有问题,速度问题与存储问题的比率相当高:-)
而且,虽然这在技术上“打破”了复制数据的3NF,但出于性能原因,如果您知道自己在做什么(即,触发器可以减轻“损害”)。既然您不需要年份,就从日期中减去它。
在MySQL中,您可以执行以下操作:
select * from some_table
where date_sub(date_col, interval year(date_col) year)
between '0000-06-21' and '0000-09-21';
右功能可能会有所帮助
select
current_date,
right(current_date,5),
right(current_date,5) between '06-21' and '09-21' `IsTodaySummer?`,
'09-21' between '06-21' and '09-21' `Is 09-21 Summer?`;
+--------------+-----------------------+-----------------+-------------------+
| current_date | right(current_date,5) | IsTodaySummer? | Is 09-21 Summer? |
+--------------+-----------------------+-----------------+-------------------+
| 2011-09-29 | 09-29 | 0 | 1 |
+--------------+-----------------------+-----------------+-------------------+
但正如ajeal所说,添加另一列比使用索引更好。这可能是最简单的解决方案,因此+1,但您应该知道它(可能还有任何其他解决方案)可能会严重降低您的性能。是的,我也在等待聪明的解决方案。。我只是想抛开显而易见的解决方案。谢谢你的解决方案,谢谢你的建议。。。性能至关重要,我有超过100000张照片,而且增长很快。在决定应用它之前,我必须对它进行彻底的测试,只是想知道我如何使用MySQL实现这一点。这是一个非常有用的答案,谢谢。是的,我的表包含100000多行,而且增长很快,因此性能至关重要。我已经将我的一些照片、关键字和事件表合并到一个表中,以允许全文索引运行得更顺畅-因此我非常熟悉数据库的反规范化。明天我会测试一下,看看效果如何,再次感谢。我希望有一天会有一个内置的功能,这。。。
select
current_date,
right(current_date,5),
right(current_date,5) between '06-21' and '09-21' `IsTodaySummer?`,
'09-21' between '06-21' and '09-21' `Is 09-21 Summer?`;
+--------------+-----------------------+-----------------+-------------------+
| current_date | right(current_date,5) | IsTodaySummer? | Is 09-21 Summer? |
+--------------+-----------------------+-----------------+-------------------+
| 2011-09-29 | 09-29 | 0 | 1 |
+--------------+-----------------------+-----------------+-------------------+