如何在SQL中解析日期?

时间:2014-05-29 02:46:45

标签: php mysql sql

我将日期存储在varchar格式的表中,如下所示:

2014年5月29日

年月日

所以我认为,对于使用BETWEEN选项,我可以摆脱破折号(20140529)并在两个日期之间轻松选择。例如,在2014-01-01和2014-02-01之间的日期将被视为20140101和20140201,并且这些日期之间显然存在与实际日期值匹配的数字范围,例如20140115。

这是我计划在两个日期之间选择的SQL查询(在php文件中):

$sql = mysql_query("Select * From $table Where Symbol = $symbol 
                And (Concat(Parsename(Replace(Date, '-', '.'), 3), Parsename(Replace(Date, '-', '.'), 2), Parsename(Replace(Date, '-', '.'), 1))
                    Between Concat(Parsename(Replace($lowDate, '-', '.'), 3), Parsename(Replace($lowDate, '-', '.'), 2), Parsename(Replace($lowDate, '-', '.'), 1)) And
                        Concat(Parsename(Replace($highDate, '-', '.'), 3), Parsename(Replace($highDate, '-', '.'), 2), Parsename(Replace($highDate, '-', '.'), 1))))");

所以我在这里做的是使用parsename函数获取每个索引(它获取由点分隔的字符串,但首先用点替换破折号以使其工作)。它应该按顺序获得年,月和日,然后将它们连接起来。

根据我的理解,每个日期应该这样做;存储在表中的日期数据,然后是低日期和高日期(我想要数据之间),它们已经存储为php中的变量。然后它应该看看日期是在低日期和高日期之间。我不确定为什么这不起作用,任何帮助都会很棒。

3 个答案:

答案 0 :(得分:3)

它不起作用,因为PARSENAME不是MySQL函数。如果要删除破折号,只需使用REPLACE()功能删除破折号即可。没有必要将字符串切断并将其连接在一起。

REPLACE(mycol,'-','')

e.g。

WHERE REPLACE(mycol,'-','') BETWEEN '20140101' AND '20140430'

但由于字符串已经是规范格式,因此删除短划线并不是必需的。也就是说,因为这些值都是YYYY-MM-DD格式,长度恰好是10个字符,带有两位数的月和日(带前导零),然后让你的谓词在裸列上操作...只需格式化另一个"日期"将值作为相同格式的字符串,例如

mycol BETWEEN '2013-12-01' AND '2014-02-15'

使用此表单,因为谓词位于裸VARCHAR列上,MySQL应该能够使用适当的索引来执行范围扫描操作。

要将字符串转换为实际的MySQL DATE ,您可以执行以下操作:

mycol + INTERVAL 0 DAY

您可以在SQL语句中使用该表达式,例如

mycol + INTERVAL 0 DAY BETWEEN '2013-12-15' AND '2014-03-31' 

(使用这种形式,因为谓词是在表达式而不是裸列表上运行,MySQL优化器不能使用范围扫描操作来满足谓词。 BETWEEN的左侧需要针对每一行进行评估(在评估此项之前,不会被其他谓词排除。)

注意 MySQL提供 DATE 数据类型,非常适合存储" date"值。存储"日期" VARCHAR中的值是反模式。

答案 1 :(得分:0)

在mysql中使用DATE格式。 如果有YYYY-MM-DD格式,您可以简单地使用 $date3 =>初始日期 $date4 =>最后日期

query="SELECT * FROM table where date1 >='$date3' AND date2 <='$date4'";

前提是mySql中的date1date2字段定义为date类型。

答案 2 :(得分:0)

虽然我最好的建议是将您的应用程序转换为MySQL DATE类型的商店日期,但对于您当前的情况,有一个简单的解决方法。

如果您在此处使用YYYY-MM-DD形式表示,则日期已经作为字符串正确排序。 (也就是说,给定两个日期A和B,当且仅当日期A在日期B之前时,字符串A将始终比字符串B小。)因此,您不需要在日期B进行任何转换。所有这些 - 只需检查Date列是否在字符串$lowDate$highDate之间就足够了。

我对您目前获得的PHP代码不满意(mysql扩展已弃用,我有点担心可能的SQL注入),但是,使用以您提供的示例为例,此查询可能更简单地写为:

SELECT * FROM $table WHERE Symbol = $symbol AND Date BETWEEN '$lowDate' and '$highDate'

另外,值得注意的是:如果您在内部转换为使用DATE,则相同的代码也可以使用。它会开始更好地工作。