将保存为 varchar 的日期与 DateTime 进行比较

Compare Date saved as varchar with DateTime

我有一个 table,其列 jsonStr 类型为 varchar

这是此列中元素的示例

{"Date":"/Date(1602846000000)/","person":"Laura"}

我想将此日期与静态日期进行比较。这是我的查询:

select * 
from mytable 
where json_value(jsonStr, '$.Date') >= '2020-10-01T00:00:00'

我希望显示一个元素但没有结果所以我如何转换这个日期以将其与 DateTime 进行比较

我尝试使用子字符串删除 /Date 和 /,然后转换/解析结果 1602846000000 但没有结果

提取的 unixtime 值可能会通过使用

转换为日期时间格式

DATEADD(S, CONVERT(int,LEFT(1602846000000, 10)), '1970-01-01') 如:

WITH t AS
(
SELECT *, JSON_VALUE(jsonStr, '$.Date') AS str
  FROM mytable 
), t2 AS
(
SELECT t.*, 
       SUBSTRING(str, PATINDEX('%[0-9]%', str), PATINDEX('%[0-9][^0-9]%', str + 't') 
       - PATINDEX('%[0-9]%', str) + 1) AS nr
  FROM t
)
SELECT t2.jsonStr
  FROM t2
 WHERE DATEADD(S, CONVERT(int,LEFT(nr, 10)), '1970-01-01') >= '2020-10-01T00:00:00'

Demo

我会尽可能扭转这一局面。您为此比较所做的每一点工作都必须针对 table 中的每一行完成,因为在我们完成工作之前我们不知道哪些行将匹配。我们对常量值(而不是所有存储值)做的越多,查询的效率就越高。

从 JSON 中解析日期在数据库中是非常昂贵的。我们不能完全摆脱这项工作,但我们至少可以在包含在 SQL 之前将初始日期字符串转换为 unix 时间格式。所以这个:

'2020-10-01T00:00:00'

变成这样:

1601510400

现在您可以进行一些更简单的字符串操作并比较数字,而无需将每一行的 unix 时间转换为日期值。

根据您拥有的 Sql 服务器版本,字符串操作的外观有很大差异。 Sql Server 2019 添加了一些 new native JSON support,这可以使这更容易。

但无论哪种方式,您最好花时间了解您正在存储的数据。即使保留原始 json 有意义,您也应该有一个至少支持其上的基本元数据的模式。使用索引与不使用索引之间的区别,可以使性能相差多个数量级。

例如,如前所述,此问题中的查询必须提取 table 中每一行的日期值...即使是不匹配的行。如果您构建一个架构,其中日期被标识为元数据并在初始插入期间提取,则索引可以让您只查找所需的行。如果此时您仍然需要从 JSON 条记录中提取值,至少它只是针对相关行。

我使用

解决了这个问题
DATEADD(SECOND, CONVERT(INT, Left(SUBSTRING(JSON_VALUE(jsonStr, '$.EndDate'), 7, 13), 10)), '19700101'