我希望能够选择mysql数据库中两个日期之间的所有日期,其中日期是格式为dd.mm.yyyy的varchar。
Database
date (varchar) | value
------------------------
31.01.2018 | 123
------------------------
28.02.2018 | 456
这行不通
Query
SELECT date,value from Database WHERE date BETWEEN '2018-01-01' AND '2018-01-31'
我知道我需要 WHERE date LIKE '%.01.2018'
整整几个月,但这还不够。
我可以用php来做这个,但不想这样做,因为那样会花太长时间。我想我可以用 CAST
功能,但不确定如何。
在mysql中最好的方法是什么?
3条答案
按热度按时间wz1wpwve1#
你可以选择revo的解决方案,或者,这个
在这里,我们检查date是否不为null以及是否为所需的长度,这样当程序遇到非常规值时就不会崩溃。
vd2z7a6w2#
你可以用
STR_TO_DATE()
:rqqzpn5f3#
在mysql中,最好的方法是避免将日期存储为dd.mm.yyyy格式的字符串。相反,把日期储存在适当的地方
DATE
列,因此它们匹配本机格式:yyyy-mm-dd。使用的解决方案
STR_TO_DATE()
或者其他函数意味着不能使用索引来优化比较。搜索将以较差的性能运行,因为它必须执行表扫描。请回复您的意见:
200万行不是一个大表。重组不应该超过一两分钟。如果你等到table变大的时候,事情只会变得更难。
由于您的数据格式错误,因此不能仅更改数据类型。下面是我将如何解决这个问题:
步骤1:添加一个新列,该列是正确的
DATE
数据类型:(顺便说一下,不要将表命名为“database”或列命名为“date”。这些都是保留字,无论如何都不是描述性的。你把程序变量命名为“variable”吗
第2步:创建触发器,以便应用程序对旧列的使用自动复制到新列:
联合的原因一会儿就会清楚。
步骤3:回填过去行中的所有值:
你只需要做一次。创建触发器后,插入的任何新行都将自动将正确的日期值复制到新列。在创建触发器之前插入的任何行在新列中都将为null,因此需要如上所示更新它们。
第4步:更改应用程序代码,以便任何对旧的错误日期列的引用都使用新的日期列。地址引用日期的任何插入、更新或选择。测试并部署此代码更改。
执行此操作后,任何insert或update都将在new date列中指定一个值,而不是null。这将使触发器有效地成为no op,因为mydate中的非null值将优先于str\u to\u date()表达式。这允许您在方便的时候部署代码,而数据库将继续对您的数据执行正确的操作。
步骤5:删除触发器和旧字符串日期列:
如果您担心在表重组期间每个alter表都会锁定表,那么应该学习使用pt online schema change。这允许您在不锁定的情况下执行alter表(除了重组结束时的短暂时刻)。