0

我有一个jsonStr类型为列的表varchar

这是此列中元素的示例

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

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

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

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

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

4

3 回答 3

0

我解决了这个问题

DATEADD(SECOND, CONVERT(INT, Left(SUBSTRING(JSON_VALUE(jsonStr, '$.EndDate'), 7, 13), 10)), '19700101'
于 2020-09-10T19:35:38.617 回答
0

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

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

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

变成这样:

1601510400

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

字符串操作的外观会因您拥有的 Sql Server 版本而有很大差异。Sql Server 2019 添加了一些新的原生 JSON 支持,这可以让这变得更容易。

但无论哪种方式,您最好还是花时间了解您存储的数据。即使保留原始 json 是有意义的,您也应该有一个至少支持基本元数据的模式。是否使用索引是有区别的,它可以使性能产生多个数量级的差异。

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

于 2020-09-10T17:32:22.010 回答
0

提取的 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

于 2020-09-10T16:28:56.960 回答