【问题标题】:SQL Server : read nested JSON from a table and find the MAX valueSQL Server:从表中读取嵌套的 JSON 并找到 MAX 值
【发布时间】:2021-11-24 13:02:38
【问题描述】:

我有json字符串

DECLARE @json nvarchar(max)
SET @json = '{"value": [
    {
        "AEDAT": "20211119",
        "ERDAT": "20211119"
    },
    {
        "AEDAT": "20211119",
        "ERDAT": "20211112"
    },
    {
        "AEDAT": "20211123",
        "ERDAT": "20211123"
    },
    {
        "AEDAT": "00000000",
        "ERDAT": "20211119"
    },
    {
        "AEDAT": "00000000",
        "ERDAT": "20211123"
    }]}'

然后当我使用OPENJSON 然后(仅第一两行):

key         value                                 type
 0    {"AEDAT": "20211119", "ERDAT": "20211119"}    5
 1    { "AEDAT": "20211119", "ERDAT": "20211112"}   5

我想MAX value 列的值。所以在上面的例子中,结果应该是 20211119。

基于这里1 并根据某人的建议,我得到的错误是

将 nvarchar 值 '{"AEDAT": "20211119", "ERDAT": "20211119"}' 转换为数据类型 int 时转换失败。

关于如何实现相同的任何线索?我是 SQL Server 的新手,因此寻求帮助。

【问题讨论】:

  • 看看OPENJSON。那么它字面意思就像使用MAX一样简单。
  • 提问时,您需要提供minimal reproducible example: (1) DDL 和样本数据填充,即 CREATE 表和 INSERT T-SQL 语句。 (2) 你需要做什么,即逻辑和你的代码尝试在 T-SQL 中实现它。 (3) 期望的输出,基于上述#1 中的样本数据。 (4) 您的 SQL Server 版本 (SELECT @@version;)。
  • 提示:在从 openjson 返回的 JSON 列上交叉应用 openjson。它甚至在帮助文档中进行了演示。
  • @YitzhakKhabinsky:我已经更新了问题。

标签: json sql-server tsql


【解决方案1】:

如果您的 JSON 键是动态的,并且您想要 any 键的最大值,最简单的方法是再次使用 OPENJSON 来取消转置键

SELECT
  MAX(CAST(j2.value AS int))
FROM OPENJSON(@json, '$.value') j1
CROSS APPLY OPENJSON(j1.value) j2;

要获取关联的密钥,您可以改用TOP

SELECT TOP (1)
  j1.[key] ArrayIndex,
  j2.[key],
  CAST(j2.value AS int) MaxValue
FROM OPENJSON(@json, '$.value') j1
CROSS APPLY OPENJSON(j1.value) j2
ORDER BY
  MaxValue DESC;

【讨论】:

  • 这很棒。假设我想获取我拥有 max() 值的关联键。如果有平局,那么任何钥匙都可以。我们可以这样做吗?
  • 是的当然有修改
【解决方案2】:

请尝试以下解决方案。

计算最大值分为两步:

  1. 对于每一行。
  2. 整个数据集所有行的全局单一最大值。

SQL

DECLARE @j NVARCHAR(MAX) = 
N'{"value": [
    {
        "AEDAT": "20211119",
        "ERDAT": "20211119"
    },
    {
        "AEDAT": "20211119",
        "ERDAT": "20211112"
    },
    {
        "AEDAT": "20211123",
        "ERDAT": "20211123"
    },
    {
        "AEDAT": "00000000",
        "ERDAT": "20211119"
    },
    {
        "AEDAT": "00000000",
        "ERDAT": "20211123"
    }]}';

WITH rs AS
(
    SELECT *
    , (SELECT MAX(val) FROM (VALUES (AEDAT), (ERDAT)) AS v(val)) AS MaxValue
    FROM OPENJSON(@j,'$.value') WITH (
          AEDAT int '$.AEDAT',
          ERDAT int '$.ERDAT'
       )
)
SELECT MAX(rs.MaxValue) AS result
FROM rs;

输出

+----------+
|  result  |
+----------+
| 20211123 |
+----------+

【讨论】:

  • 假设我想动态传递 AEDATERDAT 并且它可能超过两列或只有一列。我该如何处理?
猜你喜欢
  • 2016-09-10
  • 2022-01-03
  • 2021-10-14
  • 1970-01-01
  • 2020-11-09
  • 2019-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多