[英]How can I query with SQL Server 2017 for nested values in JSON?
我必須使用 SQL Server 從 JSON 格式的列中提取信息。 問題是它嵌套在數組中的一個對象中的一個數組中的不同對象中 - 我有點迷失了方向。 在下面的代碼示例中,我只提取了動作數組 - 然后我被卡住了。 不幸的是,我對這個不太熟悉。
我使用 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"
}
]
}
]
}
因此,例如,我需要找到鍵“Gender”的值,其中鍵“BirthDay”的值不為空:在這種情況下為“Female”。 為了清楚起見,我省略了條目數組中的其他對象。
歡迎任何幫助!
您可以嘗試使用OPENJSON()獲取數據。 通過這種方法,您可以從嵌套的JSON
數組中獲取key/value
對,即使該數組具有不同的鍵名。 您需要的是使用AS JSON
子句引用 JSON 對象或數組。
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"
}
]
}
]
}'
獲取“性別”和“生日”:
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'
輸出:
Birthday Gender
"2000-01-29T10:34:12.000Z" Female
獲取完整的 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
輸出:
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
更新:
如果您有 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
輸出:
JsonData key value type
{"actions": "value1"} actions value1 1
{"actions": "value2"} actions value2 1
如果這對您有幫助,請告訴我。
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.