SQL Server 2016 存储过程中的串联 OPENJSON
Posted
技术标签:
【中文标题】SQL Server 2016 存储过程中的串联 OPENJSON【英文标题】:A concatenation OPENJSON in a SQL Server 2016 stored procedure 【发布时间】:2019-08-26 14:01:01 【问题描述】:我需要为特定的 UID 组合所有作者。基本字段在另一篇文章的代码中工作。
DECLARE @json NVARCHAR(MAX)
SET @json = '
"header":
"type": "esummary",
"version": "0.3"
,
"result":
"uids": [
"17784783",
"19505939",
"30166592"
],
"17784783":
"uid": "17784783",
"pubdate": "2007 Aug",
"epubdate": "2007 Jul 20",
"source": "PLoS Comput Biol",
"sortpubdate": "2007/08/01 00:00",
"authors": [
"name": "Yu Y",
"authtype": "Author",
"clusterid": ""
,
"name": "Wang G",
"authtype": "Author",
"clusterid": ""
,
"name": "Simha R",
"authtype": "Author",
"clusterid": ""
]
,
"19505939":
"uid": "19505939",
"pubdate": "2009 Aug 1",
"epubdate": "2009 Jun 8",
"source": "Bioinformatics",
"sortpubdate": "2009/08/01 00:00"
,
"authors": [
"name": "Zang C",
"authtype": "Author",
"clusterid": ""
],
"30166592":
"uid": "30166592",
"pubdate": "2019 Jan",
"epubdate": "2018 Aug 30",
"source": "Oncogene",
"sortpubdate": "2019/01/01 00:00",
"authors": [
"name": "Sun J",
"authtype": "Author",
"clusterid": ""
,
"name": "Cai X",
"authtype": "Author",
"clusterid": ""
],
'
我想结束
uid sortpubdate epubdate Authors
-----------------------------------------------------------------------
17784783 2007/08/01 00:00 2007 Jul 20 Yu Y,Wang G,Simha R
19505939 2009/08/01 00:00 2009 Jun 8 Simha R
30166592 2019/01/01 00:00 2018 Aug 30 Sun J, Cai, X
我从 OPENJSON syntax in a stored procedure in SQL Server 2016 的 Zohar Peled 那里得到了很好的答复,现在我需要看看我能否完成第一部分。
SELECT [uid], [sortpubdate], [epubdate]
FROM OPENJSON(@json, N'$.result') AS items
CROSS APPLY
-- parse each object in the array
OPENJSON(items.[value])
WITH(
[uid] nvarchar(max) N'$.uid' ,
[sortpubdate] nvarchar(max) N'$.sortpubdate',
[epubdate] nvarchar(max) N'$.epubdate'
) As content
WHERE [key] <> 'uids' -- Get only the relevant content
【问题讨论】:
基本上,您可以使用相同的技术(交叉应用到另一个 openjson)来获取每个uid
的作者姓名和stuff
and for xml
的组合以刺激string_agg
(已介绍,时尚迟到,仅适用于 2017 版)。
类似于 SELECT stuff(( SELECT '', '' + cast(name as varchar(max)) FROM @json FOR XML PATH('''') ), 1, 2, '' '')
不完全-您需要首先使用另一个openjson
(还有另一个cross apply
)从json中提取名称-交叉应用的结果应该连接成一个逗号分隔的字符串对于主查询中的每一行。
对不起-听起来我头顶。我一直在谷歌搜索,但找不到答案
【参考方案1】:
你发布的json有点乱,所以我编辑了。
下一个查询应该使用公用表表达式以及stuff
和for xml
的组合为您提供包括作者姓名在内的结果。
固定的json:
DECLARE @json NVARCHAR(MAX) =
'
"header":
"type": "esummary",
"version": "0.3"
,
"result":
"17784783":
"uid": "17784783",
"pubdate": "2007 Aug",
"epubdate": "2007 Jul 20",
"source": "PLoS Comput Biol",
"sortpubdate": "2007/08/01 00:00",
"authors": [
"name": "Yu Y",
"authtype": "Author",
"clusterid": ""
,
"name": "Wang G",
"authtype": "Author",
"clusterid": ""
,
"name": "Simha R",
"authtype": "Author",
"clusterid": ""
]
,
"19505939":
"uid": "19505939",
"pubdate": "2009 Aug 1",
"epubdate": "2009 Jun 8",
"source": "Bioinformatics",
"sortpubdate": "2009/08/01 00:00",
"authors": [
"name": "Zang C",
"authtype": "Author",
"clusterid": ""
]
,
"30166592":
"uid": "30166592",
"pubdate": "2019 Jan",
"epubdate": "2018 Aug 30",
"source": "Oncogene",
"sortpubdate": "2019/01/01 00:00",
"authors": [
"name": "Sun J",
"authtype": "Author",
"clusterid": ""
,
"name": "Cai X",
"authtype": "Author",
"clusterid": ""
]
,
"uids": [
"17784783",
"19505939",
"30166592"
]
';
使用公用表表达式从 json 中提取值:
WITH CTE AS
(
SELECT [uid],
[sortpubdate],
[epubdate],
[name]
FROM OPENJSON(@json, N'$.result') AS items
CROSS APPLY
-- parse each object in the array
OPENJSON(items.[value])
WITH(
[uid] nvarchar(max) N'$.uid' ,
[sortpubdate] nvarchar(max) N'$.sortpubdate',
[epubdate] nvarchar(max) N'$.epubdate',
-- Note the AS JSON on the next row - will not work without it!
[authors] nvarchar(max) N'$.authors' AS JSON
) As content
CROSS APPLY
OPENJSON([authors])
WITH ([name] nvarchar(max) N'$.name')
As authorsNames
WHERE items.[key] <> 'uids' -- Get only the relevant content
)
并使用stuff
和for xml
查询cte:
SELECT DISTINCT [uid],
[sortpubdate],
[epubdate],
STUFF((
SELECT ',' + [name]
FROM CTE As t1
WHERE t1.[uid] = t0.[uid]
FOR XML PATH('')
), 1, 1, '') As authors
FROM CTE As t0
结果:
uid sortpubdate epubdate authors
17784783 2007/08/01 00:00 2007 Jul 20 Yu Y,Wang G,Simha R
19505939 2009/08/01 00:00 2009 Jun 8 Zang C
30166592 2019/01/01 00:00 2018 Aug 30 Sun J,Cai X
【讨论】:
太棒了 - 这太棒了 我已经编辑了我的答案给你一个完整的解决方案。 这是一个超越的努力以上是关于SQL Server 2016 存储过程中的串联 OPENJSON的主要内容,如果未能解决你的问题,请参考以下文章
我应该如何使用 sql server 中的存储过程将列名存储在变量中?
如何将 SQL Server 存储过程迁移到 Mysql [关闭]