MSSQL varchar 和 PHP 字符串之间的日期比较不起作用 - 为什么?

Date comparison between MSSQL varchar and PHP string does not work - why?

所以我在 Microsoft SQL Server 11 上得到了一个数据库 运行,其中 table hpfc_prices 包含按时间顺序排列的多个条目,大致看起来像这个:

|date (varchar(255))|time (varchar(255))|price (decimal(25,10))|
|===================|===================|======================|
|01.01.2016         |00:00              |[some value]          |
|01.01.2016         |01:00              |[some value]          |
|01.01.2016         |02:00              |[some value]          |
|...                |...                |...                   |
|01.01.2016         |23:00              |[some value]          |
|02.01.2016         |00:00              |[some value]          |
|02.01.2016         |01:00              |[some value]          |
|...                |...                |...                   |

本次table时间跨度为2016年1月1日至2020年12月31日,每条代表一小时。现在我想在 PHP 脚本中加载 table 的部分内容,比方说 2017 年全年。为此,我必须使用 Medoo 作为数据库框架,并且我 运行 以下代码:

$db = new medoo($database_config);
$hpfcStart = "01.01.2017";
$hpfcEnd = "31.12.2017";
$arr = $db->select("hpfc_prices",["date","time","price"],["AND" => ["date[>=]" => $hpfcStart, "date[<=]" => $hpfcEnd]]);
var_dump($arr);

Medoo 查询通过调试翻译成这个 SQL 查询:

SELECT "date","time","price" FROM "hpfc_prices" WHERE "date" >= '01.01.2017' AND "date" <= '31.01.2018

现在的问题是输出现在包含所有 table,而不仅仅是 2017 年的所有条目。我假设查询在日期比较时失败,因为 Medoo 将字符串与 varchar 进行比较.根据我的经验,这适用于 MySQL,但我不太确定 MSSQL/Medoo。谁能告诉我如何正确比较日期?

由于您比较的是字符串,因此 02.01.2016 大于 01.01.2017。你不应该将日期存储为字符串,或者如果你真的必须,至少使用可以比较的格式。也就是说,项目从大到小。那么2016.01.02会小于2017.01.01.

但是您仍然需要使用正确的格式等。使用正确的数据类型要容易得多。

如果设置了现有的格式,可以使用CONVERT,样式104,将两边都转换成DATETIME,然后进行比较。

如果你愿意使用 Medoo 的 query() function alongside quote() 那么试试这个:

WHERE convert(date, 104) >= convert('01.01.2017', 104)

郑重声明,这会降低性能。不确定 MSSQL 的索引功能,但如果可能的话我会添加一个具有此定义的索引

convert(date, 104)

php 有 these functions 允许您将字符串转换为 dateTime 对象。

sql 服务器转换函数适用于您的字符串:

select cast ('02.01.2016' as date)

returns 2016-02-01

使用php 函数创建日期时间变量并将它们作为参数传递给sql 服务器。那么您的查询类似于:

where cast([date] as date) >= @firstParameterFromPHP
and cast([date] as date) < @secondParameterFromPHP