[英]How can I query with SQL Server 2017 for nested values in JSON?
I have to extract information from a JSON formatted column with SQL Server.我必须使用 SQL Server 从 JSON 格式的列中提取信息。 The problem is that it is nested in different objects in an array in an object in an array - and I kind of lose track.
问题是它嵌套在数组中的一个对象中的一个数组中的不同对象中 - 我有点迷失了方向。 In the below code sample I only get as far as the extracting the actions array - and then I'm stuck.
在下面的代码示例中,我只提取了动作数组 - 然后我被卡住了。 I'm not too familiar with this, unfortunately.
不幸的是,我对这个不太熟悉。
I use SQL Server 2017.我使用 SQL Server 2017。
{
"actions":[
{
"class":"actions.entries.class",
"entries":[
{
"class":"actions.entry.class",
"id":null,
"key":"BirthDay",
"performance":{
"class":"actions.entry.performance.class",
"origin":null,
"originUuid":{
"class":"java.util.UUID",
"UUID":"3d6c5024-754f-477b-87bc-81d8e5ccadcd"
},
"performanceDateTime":1556012050827,
"performerUuid":{
"class":"java.util.UUID",
"UUID":"2647a005-a3a8-4362-8f2d-ddd188f500e7"
},
"registrationDateTime":null,
"userUuid":null
},
"type":"O",
"value":"\"2000-01-29T10:34:12.000Z\""
},
{
"class":"actions.entry.class",
"id":null,
"key":"Gender",
"performance":{
"class":"actions.entry.performance.class",
"origin":null,
"originUuid":{
"class":"java.util.UUID",
"UUID":"3d6c5024-754f-477b-87bc-81d8e5ccadcd"
},
"performanceDateTime":1556012050827,
"performerUuid":{
"class":"java.util.UUID",
"UUID":"2647a005-a3a8-4362-8f2d-ddd188f500e7"
},
"registrationDateTime":null,
"userUuid":null
},
"type":"O",
"value":"Female"
}
]
}
]
}
So for example I need to find the value to key "Gender" where the value to key "BirthDay" is not null: "Female" in this case.因此,例如,我需要找到键“Gender”的值,其中键“BirthDay”的值不为空:在这种情况下为“Female”。 For the sake of clarity I left out other objects in the entries array.
为了清楚起见,我省略了条目数组中的其他对象。
Any help is welcome!欢迎任何帮助!
You may try to get your data using OPENJSON() .您可以尝试使用OPENJSON()获取数据。 With this approach you can get
key/value
pairs from your nested JSON
array, even if this array has different key names.通过这种方法,您可以从嵌套的
JSON
数组中获取key/value
对,即使该数组具有不同的键名。 What you need is to reference JSON object or array with AS JSON
clause.您需要的是使用
AS JSON
子句引用 JSON 对象或数组。
JSON input: JSON 输入:
DECLARE @json nvarchar(max)
SET @json = N'{
"actions":[
{
"class":"actions.entries.class",
"entries":[
{
"class":"actions.entry.class",
"id":null,
"key":"BirthDay",
"performance":{
"class":"actions.entry.performance.class",
"origin":null,
"originUuid":{
"class":"java.util.UUID",
"UUID":"3d6c5024-754f-477b-87bc-81d8e5ccadcd"
},
"performanceDateTime":1556012050827,
"performerUuid":{
"class":"java.util.UUID",
"UUID":"2647a005-a3a8-4362-8f2d-ddd188f500e7"
},
"registrationDateTime":null,
"userUuid":null
},
"type":"O",
"value":"\"2000-01-29T10:34:12.000Z\""
},
{
"class":"actions.entry.class",
"id":null,
"key":"Gender",
"performance":{
"class":"actions.entry.performance.class",
"origin":null,
"originUuid":{
"class":"java.util.UUID",
"UUID":"3d6c5024-754f-477b-87bc-81d8e5ccadcd"
},
"performanceDateTime":1556012050827,
"performerUuid":{
"class":"java.util.UUID",
"UUID":"2647a005-a3a8-4362-8f2d-ddd188f500e7"
},
"registrationDateTime":null,
"userUuid":null
},
"type":"O",
"value":"Female"
}
]
}
]
}'
Get "Gender" and "Birthday":获取“性别”和“生日”:
SELECT
t1.[value] AS Birthday,
t2.[value] AS Gender
FROM OPENJSON(@json, '$.actions')
WITH (
class nvarchar(max) '$.class',
entries nvarchar(max) '$.entries' AS JSON
) j
CROSS APPLY OPENJSON(j.entries)
WITH (
[key] nvarchar(100) '$.key',
[value] nvarchar(100) '$.value'
) t1
CROSS APPLY OPENJSON(j.entries)
WITH (
[key] nvarchar(100) '$.key',
[value] nvarchar(100) '$.value'
) t2
WHERE
t1.[key] = 'Birthday' AND
t2.[key] = 'Gender'
Output:输出:
Birthday Gender
"2000-01-29T10:34:12.000Z" Female
Get full JSON data:获取完整的 JSON 数据:
SELECT
t1.class,
t2.id, t2.[key], t2.[type], t2.[value],
t3.class, t3.origin, t3.performanceDateTime, t3.registrationDateTime, t3.userUuid,
t4.class1, t4.UUID1,
t5.class2, t5.UUID2
FROM OPENJSON(@json, '$.actions')
WITH (
class nvarchar(max) '$.class',
entries nvarchar(max) '$.entries' AS JSON
) t1
CROSS APPLY OPENJSON(t1.entries)
WITH (
class nvarchar(1000) '$.class',
id nvarchar(100) '$.id',
[key] nvarchar(100) '$.key',
[type] nvarchar(100) '$.type',
[value] nvarchar(100) '$.value',
performance nvarchar(max) '$.performance' AS JSON
) t2
CROSS APPLY OPENJSON (t2.performance)
WITH (
class nvarchar(1000) '$.class',
origin nvarchar(100) '$.origin',
performanceDateTime nvarchar(100) '$.performanceDateTime',
registrationDateTime nvarchar(100) '$.registrationDateTime',
userUuid nvarchar(100) '$.userUuid',
originUuid nvarchar(max) '$.originUuid' AS JSON,
performerUuid nvarchar(max) '$.performerUuid' AS JSON
) t3
CROSS APPLY OPENJSON (t3.originUuid)
WITH (
class1 nvarchar(1000) '$.class',
UUID1 nvarchar(100) '$.UUID'
) t4
CROSS APPLY OPENJSON (t3.originUuid)
WITH (
class2 nvarchar(1000) '$.class',
UUID2 nvarchar(100) '$.UUID'
) t5
Output:输出:
class id key type value class origin performanceDateTime registrationDateTime userUuid class1 UUID1 class2 UUID2
actions.entries.class BirthDay O "2000-01-29T10:34:12.000Z" actions.entry.performance.class 1556012050827 java.util.UUID 3d6c5024-754f-477b-87bc-81d8e5ccadcd java.util.UUID 3d6c5024-754f-477b-87bc-81d8e5ccadcd
actions.entries.class Gender O Female actions.entry.performance.class 1556012050827 java.util.UUID 3d6c5024-754f-477b-87bc-81d8e5ccadcd java.util.UUID 3d6c5024-754f-477b-87bc-81d8e5ccadcd
Update:更新:
If you have JSON data as values in table column, use this approach to get data:如果您有 JSON 数据作为表列中的值,请使用此方法获取数据:
CREATE TABLE #Data (
JsonData nvarchar(max)
)
INSERT INTO #Data
(JsonData)
VALUES
(N'{"actions": "value1"}'),
(N'{"actions": "value2"}')
SELECT *
FROM #Data d
CROSS APPLY OPENJSON(d.JsonData) j
Output:输出:
JsonData key value type
{"actions": "value1"} actions value1 1
{"actions": "value2"} actions value2 1
Let me know if this help you.如果这对您有帮助,请告诉我。
DECLARE @json nvarchar(max) = N'{
"actions":[
{
"class":"actions.entries.class",
"entries":[
{
"class":"actions.entry.class",
"id":null,
"key":"BirthDay",
"performance":{
"class":"actions.entry.performance.class",
"origin":null,
"originUuid":{
"class":"java.util.UUID",
"UUID":"3d6c5024-754f-477b-87bc-81d8e5ccadcd"
},
"performanceDateTime":1556012050827,
"performerUuid":{
"class":"java.util.UUID",
"UUID":"2647a005-a3a8-4362-8f2d-ddd188f500e7"
},
"registrationDateTime":null,
"userUuid":null
},
"type":"O",
"value":"\"2000-01-29T10:34:12.000Z\""
},
{
"class":"actions.entry.class",
"id":null,
"key":"Gender",
"performance":{
"class":"actions.entry.performance.class",
"origin":null,
"originUuid":{
"class":"java.util.UUID",
"UUID":"3d6c5024-754f-477b-87bc-81d8e5ccadcd"
},
"performanceDateTime":1556012050827,
"performerUuid":{
"class":"java.util.UUID",
"UUID":"2647a005-a3a8-4362-8f2d-ddd188f500e7"
},
"registrationDateTime":null,
"userUuid":null
},
"type":"O",
"value":"Female"
}
]
}
]
}';
SELECT
[PVT].[action_index]
,[CNV].[BirthDay]
,[PVT].[Gender]
FROM
(
SELECT
[action_index] = [actions].[key]
,[entry_field] = [entries].[key]
,[entry_value] = [entries].[value]
FROM OPENJSON(@json, '$.actions') AS [actions] -- iterate over actions array
OUTER APPLY OPENJSON([actions].[value], '$.entries') -- iterate over entries array for each action
WITH
(
[key] nvarchar(128)
,[value] nvarchar(max)
) AS [entries]
) AS [SRC]
PIVOT
(
MAX([entry_value]) FOR [entry_field] IN ([BirthDay], [Gender]) -- pivot the data only for the required fields
) AS [PVT]
CROSS APPLY
(
SELECT
[BirthDay] = TRY_CONVERT(datetimeoffset, NULLIF(REPLACE([BirthDay], '"', ''), ''))
) AS [CNV]
WHERE (1 = 1)
AND ([CNV].[BirthDay] IS NOT NULL);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.