从 JSON 数组中获取每行多条记录

Posted

技术标签:

【中文标题】从 JSON 数组中获取每行多条记录【英文标题】:Get multiple records per row from JSON array 【发布时间】:2020-04-15 04:49:53 【问题描述】:

我无法理解如何从单行中提取多个值,其中每一行的 JSON 数组中都有源。

设置可能有点傻,但就是这样。

表格:

LogID       [int]
LogContent  nvarchar(max)

内容:

╔═══════╦══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ LogID ║ LogContent (JSON in nvarchar)                                                                                        ║
╠═══════╬══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ 1     ║ ["DateTime":"2020-04-15T00:00:31","PropertyIWant":"ABC", "DateTime":"2020-04-15T00:00:32","PropertyIWant":"DEF"] ║
║ 2     ║ ["DateTime":"2020-04-15T00:00:33","PropertyIWant":"GHI", "DateTime":"2020-04-15T00:00:34","PropertyIWant":"JKL"] ║
╚═══════╩══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝

我想要的结果:

╔═══╦═════════════════════╦═══════════════╗
║   ║ DateTime            ║ PropertyIWant ║
╠═══╬═════════════════════╬═══════════════╣
║ 1 ║ 2020-04-15T00:00:31 ║ ABC           ║
║ 2 ║ 2020-04-15T00:00:32 ║ DEF           ║
║ 3 ║ 2020-04-15T00:00:33 ║ GHI           ║
║ 4 ║ 2020-04-15T00:00:34 ║ JKL           ║
╚═══╩═════════════════════╩═══════════════╝

我用 CROSS APPLY 和 JSON_QUERY 尝试了一些东西,但直到现在都没有运气。

一个例子是:

SELECT jt.PropertyIWant FROM Table CROSS APPLY
(
    SELECT * FROM OPENJSON (Table.LogContent) WITH (DateTime datetimeoffset](7), PropertyIWant nvarchar(255) '$.PropertyIWant')
) jt

但是当数据库中只有 77 行时,这将返回 219.851 行。在我的数据库中,它应该返回大约 13.000 条记录。

【问题讨论】:

这些你尝试过的东西,请给我们看看。 你的陈述很好(尽管CROSS APPLY OPENJSON 已经足够了)。使用问题中的数据,此语句返回 4 行,这是正确的结果,因为每个 JSON 数组中每行有 2 个项目。您可以发布返回错误结果的测试数据吗? 谢谢 Zhorov,我忘记了 WHERE 声明。这导致许多其他 JSON 返回 NULL,并且还有很多未预期的结果。 【参考方案1】:

如果您的数据库版本是 2016+,那么您可以使用嵌套在 OPENJSON 函数中的 JSON_QUERY 包含 WITH 子句解释返回列的模型:

SELECT DateTime, PropertyIWant
  FROM tab
  CROSS APPLY OPENJSON(JSON_QUERY(LogContent, '$'))
           WITH (DateTime      nvarchar(500) '$.DateTime',
                 PropertyIWant nvarchar(500) '$.PropertyIWant');

Demo

【讨论】:

谢谢,我已经对此进行了测试,并在 Dale K 要求后将其包含在内。不幸的是,它返回相同数量的记录,219.851。 这很奇怪,复制了一张表,只复制了3条测试记录,然后它给出了预期的结果,我先检查一下为什么和如何。 是的。我只是愚蠢.. Log 表中有更多记录,它记录了我没有用 WHERE 排除的其他内容。谢谢!

以上是关于从 JSON 数组中获取每行多条记录的主要内容,如果未能解决你的问题,请参考以下文章

Sumologic - 将 JSON 数组拆分为多条记录

使用 mongoose 将从 JSON 接收的多条记录插入到集合中

如何在流分析组中将多条记录与字符串和空值合并

如何根据最新日期从多条记录中获取特定记录

从多条记录中获取最大日期

按记录名称获取多条记录