SQL:从 SQL Server 中的嵌套 JSON 中查找最大值
Posted
技术标签:
【中文标题】SQL:从 SQL Server 中的嵌套 JSON 中查找最大值【英文标题】:SQL:Finding max value from a nested JSON in SQL Server 【发布时间】:2022-01-03 08:57:55 【问题描述】:这个问题在this SO thread有参考。
我想计算以下 JSON 的 MAX()
值。此外,其中的键也不是固定的,因此根据上述解决方案,它们不能在代码中硬编码。
DECLARE @json nvarchar(max) = ''"value": [
"AEDAT": "20211119",
"ERDAT": "20211119"
,
"AEDAT": "20211119",
"ERDAT": "20211112"
,
"AEDAT": "20211123",
"ERDAT": "20211123"
,
"AEDAT": "00000000",
"ERDAT": "20211119"
,
"AEDAT": "00000000",
"ERDAT": "20211123"
]';
我还将从其他一些 SP 获取以下字符串作为参数。
DECLARE @ColumnName = 'AEDAT,ERDAT' ---I shall be getting this as an output from another SP.
综上所述,我的做法如下:
DECLARE @col_table TABLE (ID int IDENTITY(1,1), ColumnName varchar(100))
INSERT INTO @col_table SELECT value as ColumnName FROM STRING_SPLIT(@ColumnName,',');
DECLARE @max_val TABLE (ID int IDENTITY(1,1), LastUpdatedValue int)
DECLARE @max_ID int
DECLARE @min_ID int
DECLARE @1st_col varchar(max)
SELECT @max_ID = MAX(ID),@min_ID = MIN(ID) FROM @col_table GROUP BY ColumnName;
WHILE (@min_ID <= @max_ID)
BEGIN
SELECT @1st_col = ColumnName FROM @col_table WHERE ID = @min_ID
INSERT INTO @max_val (LastUpdatedValue)
SELECT JSON_VALUE(j.value,'$.' +@1st_col+ '' ) FROM OPENJSON(@json,'$.value') AS j
SET @min_ID = @min_ID + 1
END
理想情况下,上述方法应该给出 10 个值(AEDAT 和 ERDAT 各 5 个)但这给了我 5 个值。
SELECT * FORM @max_val;
ID LastUpdatedValue
1 20211119
2 20211112
3 20211123
4 20211119
5 20211123
我期待所有键的输出类似于UNION ALL
。如下所示
SELECT JSON_VALUE(j.value,'$.AEDAT') FROM OPENJSON(@json,'$.value') AS j
UNION ALL
SELECT JSON_VALUE(j.value,'$.ERDAT') FROM OPENJSON(@json,'$.value') AS j
我错过了什么?请提出建议。
【问题讨论】:
我的是 SQL Server 2019 【参考方案1】:您可以使用OPENJSON
两次,一次打开数组,再次取消旋转键。然后只需按您的表变量过滤
DECLARE @col_table TABLE (ColumnName varchar(100) COLLATE Latin1_General_BIN2 PRIMARY KEY)
INSERT INTO @col_table (ColumnName)
SELECT value
FROM STRING_SPLIT(@ColumnName,',');
SELECT
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)),
j2.[key],
j2.value
FROM OPENJSON(@json, '$.value') j1
CROSS APPLY OPENJSON(j1.value) j2
WHERE CAST(j2.[key] AS varchar(100)) IN (
SELECT c.ColumnName
FROM @col_table c
);
db<>fiddle
【讨论】:
遇到错误:Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Latin1_General_BIN2" in the equal to operation
好点,需要明确设置COLLATE
。您可以对表变量执行此操作,也可以在WHERE
中的比较中执行此操作
我没有得到最终表格中的列名。此外,我得到 8 行,而不是 10 行。另外,我们是否需要将ColumnName
设置为PRIMARY KEY
?
您没有询问密钥名称,已添加。我得到 10 行,请参阅小提琴dbfiddle.uk/… 请给minimal reproducible example。将ColumnName
设置为PK更高效,反正多次拥有一个key也没有意义以上是关于SQL:从 SQL Server 中的嵌套 JSON 中查找最大值的主要内容,如果未能解决你的问题,请参考以下文章
oracle sql中的JSON_TABLE未捕获嵌套的json数据