JSON到SQL - 从JSON数组中提取?

问题描述 投票:0回答:3

我有一个练习从较大的JSON对象中提取一些数据但是数据被添加为多个对象或者可能是一组排序。

以下示例;

DECLARE @json NVARCHAR(MAX) = '{
"N.data.-ce731645-e4ef-4784-bc02-bb90b4c9e9e6": "Some Data",
"N.data.sessionDates-7f1790d3-9175-43aa-962b-161ee3b8615f": [
    {
        "date_1": "2018-10-20T23:00:00.000Z"
    },
    {
        "date_1": "2018-10-21T23:00:00.000Z"
    }
]
}'

我需要从“date_1”标识符中提取这些日期时间条目,理想情况下是CSV列表。从那以后我可以做自己的操作。

2018-10-20T23:00:00.000Z, 2018-10-21T23:00:00.000Z

我熟悉JSON_VALUE(),但不是在一个简单的一维数据之外使用它。

到目前为止我所拥有的;

DECLARE @json NVARCHAR(MAX) = '{
"N.data.-ce731645-e4ef-4784-bc02-bb90b4c9e9e6": "Some Data",
"N.data.sessionDates-7f1790d3-9175-43aa-962b-161ee3b8615f": [
    {
        "date_1": "2018-10-20T23:00:00.000Z"
    },
    {
        "date_1": "2018-10-21T23:00:00.000Z"
    }
]
}'

SELECT value FROM OPENJSON(@json)

有没有办法在复杂的substring()和replace()使用之外实现预期的输出?

使用SQL Server 2017

Microsoft SQL Server 2017 (RTM) - 14.0.1000.169 (X64)   Aug 22 2017 17:04:49   Copyright (C) 2017 Microsoft Corporation  Express Edition (64-bit) on Windows Server 2012 R2 Datacenter 6.3 <X64> (Build 9600: ) (Hypervisor) 

谢谢

sql json sql-server extract
3个回答
3
投票

从SQL Server 2017开始,可以通过本机OPENJSON完成提取:

DECLARE @json NVARCHAR(MAX) = '{
"N.data.sessionDates-7f1790d3-9175-43aa-962b-161ee3b8615f": [
    {
        "date_1": "2018-10-20T23:00:00.000Z"
    },
    {
        "date_1": "2018-10-21T23:00:00.000Z"
    }
]
}'


SELECT  
    JSON_VALUE(child_value.value, '$.date_1') AS [key]    
FROM OPENJSON(@json, '$') AS nda
cross apply openjson(nda.value, '$') as child_value

结果:

key
2018-10-20T23:00:00.000Z
2018-10-21T23:00:00.000Z

有没有办法调整这个来提取特定键的值,示例中的“N.data.sessionDates-7f1790d3-9175-43aa-962b-161ee3b8615f”

在这种情况下,该查询可以略微简化为:

DECLARE @id nvarchar(200) = 'N.data.sessionDates-7f1790d3-9175-43aa-962b-161ee3b8615f'

SELECT  
    JSON_VALUE(nda.value, '$.date_1') AS [key]    
FROM OPENJSON(@json, concat('$."',@id,'"')) AS nda

或没有参数化:

SELECT  
    JSON_VALUE(nda.value, '$.date_1') AS [key]    
FROM OPENJSON(@json, '$."N.data.sessionDates-7f1790d3-9175-43aa-962b-161ee3b8615f"') AS nda

1
投票

使用带有with_clause的交叉应用OPENJSON():

DECLARE @json NVARCHAR(MAX) = '{
"N.data.sessionDates-7f1790d3-9175-43aa-962b-161ee3b8615f": [
    {
        "date_1": "2018-10-20T23:00:00.000Z"
    },
    {
        "date_1": "2018-10-21T23:00:00.000Z"
    }
]
}';

SELECT [b].*
FROM   OPENJSON(@json) [a]
CROSS APPLY
       OPENJSON([a].[Value])
           WITH (
                    [date_1] DATETIME '$.date_1'
                ) [b];

0
投票

另一种可能的方法,使用OPENJSON()。使用此方法,您可以从嵌套的JSON数组中获取key/value对,即使此数组具有不同的键名。

DECLARE @json nvarchar(max)
SET @json = 
N'{"N.data.sessionDates-7f1790d3-9175-43aa-962b-161ee3b8615f": [
    {
        "date_1": "2018-10-20T23:00:00.000Z"
    },
    {
        "date_1": "2018-10-21T23:00:00.000Z"
    },
    {
        "date_2": "2019-10-21T23:00:00.000Z"
    }
]
}'

SELECT 
   x.[key] AS SessionData, 
   z.[key],
   z.[value]
FROM OPENJSON(@json) x
CROSS APPLY (SELECT * FROM OPENJSON(x.[value])) y
CROSS APPLY (SELECT * FROM OPENJSON(y.[value])) z
--WHERE z.[key] = 'date_1'

输出:

SessionData                                                 key     value
N.data.sessionDates-7f1790d3-9175-43aa-962b-161ee3b8615f    date_1  2018-10-20T23:00:00.000Z
N.data.sessionDates-7f1790d3-9175-43aa-962b-161ee3b8615f    date_1  2018-10-21T23:00:00.000Z
N.data.sessionDates-7f1790d3-9175-43aa-962b-161ee3b8615f    date_2  2019-10-21T23:00:00.000Z

更新:如果您想按键名称进行过滤,下一步可能有所帮助:

DECLARE @json NVARCHAR(MAX) = '{
"N.data.-ce731645-e4ef-4784-bc02-bb90b4c9e9e6": "Some Data",
"N.data.sessionDates-7f1790d3-9175-43aa-962b-161ee3b8615f": [
    {
        "date_1": "2018-10-20T23:00:00.000Z"
    },
    {
        "date_1": "2018-10-21T23:00:00.000Z"
    }
]
}'

SELECT z.[value]
--SELECT STRING_AGG(z.[value], ', ') [Data] -- with string aggregation
FROM OPENJSON(@json) x
CROSS APPLY (SELECT * FROM OPENJSON(x.[value])) y
CROSS APPLY (SELECT * FROM OPENJSON(y.[value])) z
WHERE x.[key] = 'N.data.sessionDates-7f1790d3-9175-43aa-962b-161ee3b8615f'

输出:

value
2018-10-20T23:00:00.000Z
2018-10-21T23:00:00.000Z
-- With string aggregation
--Data
--2018-10-20T23:00:00.000Z, 2018-10-21T23:00:00.000Z
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.