OPENJSON - 无法查询嵌套元素
Posted
技术标签:
【中文标题】OPENJSON - 无法查询嵌套元素【英文标题】:OPENJSON - Unable to query nested elements 【发布时间】:2019-05-13 23:23:36 【问题描述】:我在使用 SQL Server 2016 中的 T-SQL OPENJSON
函数查询 JSON 文档的嵌套元素时遇到困难。我通读了 MSDN 文档 here 、 here 和 here 但还没有找到WITH 块的正确语法。我的列一直只返回一个空行。
任何人都可以协助修改 T-SQL 以实现这样的查询输出(如下)?
这里是json结构&空输出:
DECLARE @json NVARCHAR(MAX)
SET @json = N'"meta":"total_record_count":4870,"total_pages":98,"current_page":97,"per_page":50,"companies":["id":"13463591","url":"https://api.mattermark.com/companies/13463591","company_name":"Modula4","domain":"modula4.com","id":"13531979","url":"https://api.mattermark.com/companies/13531979","company_name":"Rae Development Corp","domain":"raedevelopment.com","id":"13537660","url":"https://api.mattermark.com/companies/13537660","company_name":"jBASE","domain":"jbase.com","id":"13537769","url":"https://api.mattermark.com/companies/13537769","company_name":"D2Effects LLC","domain":"bitefx.com","id":"13537784","url":"https://api.mattermark.com/companies/13537784","company_name":"eSyncTraining","domain":"esynctraining.com","id":"13541751","url":"https://api.mattermark.com/companies/13541751","company_name":"Business Computing","domain":"bcinc.net","id":"13553270","url":"https://api.mattermark.com/companies/13553270","company_name":"KNIGHTLING INC.","domain":"knightling.com","id":"13560476","url":"https://api.mattermark.com/companies/13560476","company_name":"Netcentric systems","domain":"netcentricsystems.com","id":"13560643","url":"https://api.mattermark.com/companies/13560643","company_name":"Fortium Solutions, LLC","domain":"fortiumsolutions.com","id":"13561893","url":"https://api.mattermark.com/companies/13561893","company_name":"PMAC SERVICES INC","domain":"pmacservices.com","id":"13587256","url":"https://api.mattermark.com/companies/13587256","company_name":"Bayonet Inc.","domain":"mybayonet.com","id":"13590982","url":"https://api.mattermark.com/companies/13590982","company_name":"IQA","domain":"instrumentalqa.com","id":"13593143","url":"https://api.mattermark.com/companies/13593143","company_name":"Atech Consultants","domain":"atechconsultants.com","id":"13601156","url":"https://api.mattermark.com/companies/13601156","company_name":"Csoft Corp","domain":"csoftcorp.net","id":"13602832","url":"https://api.mattermark.com/companies/13602832","company_name":"Gareth, Inc.","domain":"garethinc.com","id":"13604890","url":"https://api.mattermark.com/companies/13604890","company_name":"Xpaseo","domain":"xpaseo.com","id":"13610146","url":"https://api.mattermark.com/companies/13610146","company_name":"Imagine IT","domain":"imagineit.com","id":"13610923","url":"https://api.mattermark.com/companies/13610923","company_name":"HTS Solutions Pvt Ltd","domain":"htssolutions.org","id":"13619836","url":"https://api.mattermark.com/companies/13619836","company_name":"Tgm Software","domain":"tgmsoftware.com","id":"13622956","url":"https://api.mattermark.com/companies/13622956","company_name":"Inaspan LLC","domain":"inaspan.com","id":"13627130","url":"https://api.mattermark.com/companies/13627130","company_name":"Forerunner Systems Inc","domain":"forerunnersystems.com","id":"13628312","url":"https://api.mattermark.com/companies/13628312","company_name":"Advanced Integrated Solutions, Inc.","domain":"aisconsulting.net","id":"13629029","url":"https://api.mattermark.com/companies/13629029","company_name":"Pounce Consulting","domain":"pouncecorp.com","id":"13629537","url":"https://api.mattermark.com/companies/13629537","company_name":"CloudServe Corporation","domain":"cloudservecorp.com","id":"13635102","url":"https://api.mattermark.com/companies/13635102","company_name":"Leivio Technologies","domain":"leivio.com","id":"13636749","url":"https://api.mattermark.com/companies/13636749","company_name":"Alpen Technology Group","domain":"alpentg.com","id":"13636754","url":"https://api.mattermark.com/companies/13636754","company_name":"National Schedule Masters","domain":"tractime.com","id":"13645065","url":"https://api.mattermark.com/companies/13645065","company_name":"RISA Technologies","domain":"risa.com","id":"13646467","url":"https://api.mattermark.com/companies/13646467","company_name":"Enterprise Answers, LLC","domain":"enterpriseanswers.com","id":"13647801","url":"https://api.mattermark.com/companies/13647801","company_name":"Office Automation Centers Inc","domain":"officeautomationcenter.com","id":"13650810","url":"https://api.mattermark.com/companies/13650810","company_name":"Mozgomedia","domain":"mozgomedia.com","id":"13652763","url":"https://api.mattermark.com/companies/13652763","company_name":"2000 Networking","domain":"network2000-hi.com","id":"13654103","url":"https://api.mattermark.com/companies/13654103","company_name":"Vega Imaging","domain":"vega-imaging.com","id":"13654874","url":"https://api.mattermark.com/companies/13654874","company_name":"Astha Inc.","domain":"asthainc.com","id":"13656103","url":"https://api.mattermark.com/companies/13656103","company_name":"Management Applied Programming","domain":"mapinc.com","id":"13657848","url":"https://api.mattermark.com/companies/13657848","company_name":"4Hilton Inc.","domain":"4hilton.com","id":"13658020","url":"https://api.mattermark.com/companies/13658020","company_name":"FCC Group","domain":"fccgroup.com","id":"13658316","url":"https://api.mattermark.com/companies/13658316","company_name":"Wavelength Datacom, Inc.","domain":"wavdata.com","id":"13661074","url":"https://api.mattermark.com/companies/13661074","company_name":"Xintex Corporation","domain":"xintex.com","id":"13663085","url":"https://api.mattermark.com/companies/13663085","company_name":"DCL Media Services","domain":"onlinecopycorp.com","id":"13667881","url":"https://api.mattermark.com/companies/13667881","company_name":"LMSPros","domain":"lmspros.com","id":"13669354","url":"https://api.mattermark.com/companies/13669354","company_name":"Sujansky \u0026 Associates, LLC","domain":"sujansky.com","id":"13669681","url":"https://api.mattermark.com/companies/13669681","company_name":"Felosoft LLC","domain":"felosoft.com","id":"13669759","url":"https://api.mattermark.com/companies/13669759","company_name":"Collaborative Technologies Inc","domain":"collaborationtech.net","id":"13670474","url":"https://api.mattermark.com/companies/13670474","company_name":"Freight Stream Inc","domain":"freightstream.com","id":"13675681","url":"https://api.mattermark.com/companies/13675681","company_name":"eDimension Consulting","domain":"edimensionconsulting.com","id":"13676806","url":"https://api.mattermark.com/companies/13676806","company_name":"LTT Net Solutions","domain":"lttnetsolutions.com","id":"13678223","url":"https://api.mattermark.com/companies/13678223","company_name":"OCRTI Consulting Corp","domain":"ocrti.com","id":"13679946","url":"https://api.mattermark.com/companies/13679946","company_name":"Mac Networks","domain":"macnetworks.com","id":"13681009","url":"https://api.mattermark.com/companies/13681009","company_name":"NetMost Web Technologies","domain":"netmostwebdesign.com"],"total_companies":4870,"page":97,"per_page":50'
SELECT *
FROM OPENJSON(@json)
WITH (
id int '$.companies.id' ,
[url] nvarchar(max) '$.companies.url',
company_name nvarchar(max) '$.companies.company_name',
domain nvarchar(max)'$.companies.domain'
)
【问题讨论】:
【参考方案1】:如果您想将所有JSON
数据作为结果集,您需要额外的APPLY
运算符和第二个OPENJSON()
调用(用于嵌套JSON
数组),使用显式架构定义:
T-SQL:
SELECT
j.total_companies, j.page, j.per_page,
a.*
FROM OPENJSON(@json)
WITH (
total_companies int '$.total_companies',
page int '$.page',
per_page int '$.per_page',
companies nvarchar(max) '$.companies' AS JSON
) j
CROSS APPLY OPENJSON(j.companies)
WITH (
id nvarchar(10) '$.id',
url nvarchar(max) '$.url',
company_name nvarchar(100) '$.company_name',
domain nvarchar(max) '$.domain'
) a
输出(仅 50 条记录中的前 10 条记录):
total_companies page per_page id url company_name domain
4870 97 50 13463591 https://api.mattermark.com/companies/13463591 Modula4 modula4.com
4870 97 50 13531979 https://api.mattermark.com/companies/13531979 Rae Development Corp raedevelopment.com
4870 97 50 13537660 https://api.mattermark.com/companies/13537660 jBASE jbase.com
4870 97 50 13537769 https://api.mattermark.com/companies/13537769 D2Effects LLC bitefx.com
4870 97 50 13537784 https://api.mattermark.com/companies/13537784 eSyncTraining esynctraining.com
4870 97 50 13541751 https://api.mattermark.com/companies/13541751 Business Computing bcinc.net
4870 97 50 13553270 https://api.mattermark.com/companies/13553270 KNIGHTLING INC. knightling.com
4870 97 50 13560476 https://api.mattermark.com/companies/13560476 Netcentric systems netcentricsystems.com
4870 97 50 13560643 https://api.mattermark.com/companies/13560643 Fortium Solutions, LLC fortiumsolutions.com
4870 97 50 13561893 https://api.mattermark.com/companies/13561893 PMAC SERVICES INC pmacservices.com
【讨论】:
【参考方案2】:Companies 在您的情况下是数组。必须选择数组元素编号才能查看数据:
SELECT *
FROM OPENJSON(@json)
WITH (
id INT '$.companies[0].id' ,
[url] NVARCHAR(MAX) '$.companies[0].url',
company_name NVARCHAR(MAX) '$.companies[0].company_name',
domain NVARCHAR(MAX) '$.companies[0].domain'
)
;
【讨论】:
此查询仅返回第一个公司元素。我希望返回公司数组中的所有公司。【参考方案3】:这很简单...
您的 JSON 包含两个对象,第一个是 meta
,似乎是 1:1
相关内容。最好直接调用JSON_VALUE()
进行查询。
第二个,companies
是一个嵌套的 JSON 数组。试试这个(为简洁起见)
DECLARE @json NVARCHAR(MAX)
SET @json = N'"meta":"total_record_count":4870,"total_pages":98,"current_page":97,"per_page":50,"companies":["id":"13463591","url":"https://api.mattermark.com/companies/13463591","company_name":"Modula4","domain":"modula4.com","id":"13531979","url":"https://api.mattermark.com/companies/13531979","company_name":"Rae Development Corp","domain":"raedevelopment.com","id":"13537660","url":"https://api.mattermark.com/companies/13537660","company_name":"jBASE","domain":"jbase.com"]'
-这会带回 meta
值
SELECT JSON_VALUE(@json,'$.meta.total_record_count') AS total_record_count
,JSON_VALUE(@json,'$.meta.total_pages') AS total_pages
,JSON_VALUE(@json,'$.meta.current_page') AS current_page
,JSON_VALUE(@json,'$.meta.per_page') AS per_page
--这会带回 companies
数组:
SELECT A.*
FROM OPENJSON(@json,'$.companies')
WITH (
id int ,
[url] nvarchar(max),
company_name nvarchar(max),
domain nvarchar(max)
) A;
提示:如果需要,您可以将它们与 CROSS JOIN
... 结合使用...
【讨论】:
以上是关于OPENJSON - 无法查询嵌套元素的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server OPENJSON 读取嵌套的 json
无法使用 OPENJSON 和 SQL Server 2017 解析具有动态键的对象数组
SQL Server中的OpenJson用于嵌套的json数据?
Openjson 在定义 nvarchar(max) 时不返回 json 对象,并且由 nvarchar(4000) 工作