简体   繁体   English

在 JSON 中添加一系列(已知的)嵌套 arrays 提取到 SQL

[英]Add a series of (known) nested arrays in a JSON extract into SQL

I have the following JSON as an example:我以以下 JSON 为例:

[{"UserDetails":[{"UserName":"Mr John Smith","UserDateOfBirth":"22/05/59","UserID":"ABC123","NotesDay1":[],"NotesDay2":[],"NotesDay3":[{"NoteID":"NI9199","Note":null}],"NotesDay4":[],"NotesDay5":[],"NotesDay6":[],"NotesDay7":[{"NoteID":"NI3423","Note":"Tried to contact, will try again later"}]}]}]

The format is that within the UserDetails array there are a number of users (just one in this example), and within each user object there are 7 arrays called NotesDay1 through to NotesDay7.格式是在 UserDetails 数组中有许多用户(在本例中只有一个),在每个用户 object 中有 7 个 arrays 称为 NotesDay1 到 NotesDay7。 Some users will have one or more objects within NotesDayX, whereas sometimes there are none.一些用户将在 NotesDayX 中拥有一个或多个对象,而有时则没有。

The desired output is as follows:想要的output如下:

USER         NoteID
ABC123       NI9199
ABC123       NI3243

etc ETC

Each user for that 7 day period needs to be displayed in this way.这 7 天内的每个用户都需要以这种方式显示。 Including any of my own code at this juncture seems to be pointless, as it presently doesn't work.在此关头包含我自己的任何代码似乎毫无意义,因为它目前不起作用。

Can anyone help?谁能帮忙?

Thanks in advance.提前致谢。

A possible approach is to use a variable as a value of path parameter for the second OPENJSON() call (SQL Server 2017 is required):一种可能的方法是使用变量作为第二次OPENJSON()调用的path参数值(需要 SQL Server 2017):

JSON: JSON:

DECLARE @json nvarchar(max) = N'
  [
     {"UserDetails": [
        {"UserName":"Mr John Smith","UserDateOfBirth":"22/05/59","UserID":"ABC123","NotesDay1":[],"NotesDay2":[],"NotesDay3":[{"NoteID":"NI9199","Note":null}],"NotesDay4":[],"NotesDay5":[],"NotesDay6":[],"NotesDay7":[{"NoteID":"NI3423","Note":"Tried to contact, will try again later"}]}, 
        {"UserName":"Mr John Smith 2","UserDateOfBirth":"22/05/59","UserID":"ABC124","NotesDay1":[],"NotesDay2":[],"NotesDay3":[{"NoteID":"NI9199","Note":null}],"NotesDay4":[],"NotesDay5":[],"NotesDay6":[],"NotesDay7":[{"NoteID":"NI3423","Note":"Tried to contact, will try again later"}]}]
     }
  ]'

Statemewnt:声明:

SELECT JSON_VALUE(j.[value], '$.UserID') AS [UserId], a.NoteId
FROM OPENJSON(@json, '$[0].UserDetails') j
CROSS APPLY (VALUES (1), (2), (3), (4), (5), (6), (7) ) v (n)
CROSS APPLY OPENJSON(j.[value], CONCAT('$.NotesDay', v.n)) WITH (
   NoteId nvarchar(10) '$.NoteID'
) a

Result:结果:

UserId用户身份 NoteId笔记编号
ABC123 ABC123 NI9199 NI9199
ABC124 ABC124 NI9199 NI9199
ABC123 ABC123 NI3423 NI3423
ABC124 ABC124 NI3423 NI3423

We do the CROSS APPLY / OPENJSON dance to peel the onion:我们使用CROSS APPLY / OPENJSON来剥洋葱:

SELECT UserID, NoteID
FROM OPENJSON(@json, '$[0].UserDetails')
WITH (
    UserID NVARCHAR(50),
    Details NVARCHAR(MAX) '$' AS JSON
)
CROSS APPLY (
    SELECT [value] AS [notes]
    FROM OPENJSON(Details)
    WHERE [key] LIKE 'NotesDay%'
) _
CROSS APPLY OPENJSON([notes])
WITH (
    NoteID NVARCHAR(50)
)

Note that this solution doesn't care how many days there are, and it works in SQL Server 2016.请注意,此解决方案不关心有多少天,它适用于 SQL Server 2016。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM