我将日期字段存储为Varchar。 当我使用此查询时:
SELECT date
FROM g_m_tit
WHERE date BETWEEN '01.10.2015' AND '31.10.2015';
它会生成错误的输出,如shown below
答案 0 :(得分:1)
在你的图片中注意前两个字符在'01'和'31'之间的关系。 between运算符使用varchar“规则”处理varchars,例如'19'介于'01'和'31'之间,这就是你得到不想要的结果的原因。您期望应用日期规则,但您的期望不准确。
不要将日期存储为字符串;但如果您因某种原因只是必须这样做,那么YYYYMMDD之类的序列就可以让您在两者之间可靠地使用。
如果您坚持使用dd.mm.yyyy模式将列存储为varchar,请尝试以下操作:
SELECT
`date`
FROM g_m_tit
WHERE str_to_date(`date`,'%d.%m.%Y') BETWEEN '2015-10-01' AND '2015-10-31';
SELECT
`date`
FROM g_m_tit
WHERE str_to_date(`date`,'%d.%m.%Y') >= '2015-10-01')
AND str_to_date(`date`,'%d.%m.%Y') < '2015-11-01';
正如您所看到的,这两个都迫使您改变数据,每次引用“日期”列时都需要这样做 - 这是非常低效的。
此外,日期是保留字,请避免使用列名作为单词。
最后一点:我更喜欢上面的第二个查询,因为我从不在日期范围之间使用。
答案 1 :(得分:1)
使用VARCHAR列,与字符串进行比较,从左到右逐字符比较。
如果您希望字符串比较用于&#34;日期&#34;比较时,日期值需要以一致和规范格式存储,首先是年份,然后是月份,然后是日期。例如&#39; 2016年1月13日&#39;
MySQL提供VARCHAR以外的数据类型,专门用于存储日期和时间值...... DATE
,DATETIME
,TIMESTAMP
。
以您拥有的格式处理存储在VARCHAR列中的日期值将是一些混乱的SQL。 MySQL将不得不扫描所有行来评估表达式;它无法使用范围扫描操作。
一种方法是将字符串转换为DATE值,并比较DATE值。
WHERE STR_TO_DATE(`date` ,'DD.MM.YYYY')
BETWEEN STR_TO_DATE('01.10.2015','DD.MM.YYYY')
AND STR_TO_DATE('31.10.2015','DD.MM.YYYY')
如果date
中的任何字符串值无法转换为DATE,因为格式与规范不匹配,或者&#34;无效&#34;日期值,例如32.13.2015
,STR_TO_DATE函数将返回NULL或抛出错误(取决于SQL_MODE设置)。
答案 2 :(得分:0)
使用&#34; date&#34;创建新列或&#34; bigint&#34;型
更新从旧列插入值到新的所有行(基于新列类型)
删除旧列
将新的重命名为&#34; g_m_tit&#34;
不要将varchar用于日期!它导致你可以看到的问题,它比date / bigint慢。
将日期存储在:
&#34; VARCHAR(10)&#34;你需要11个字节+字符集整理每个查询
&#34; BIGINT&#34;你需要8个字节(可用范围条件)
&#34;日期&#34;你需要3个字节(可用范围,部分日期条件等等)