在T-SQL中解析JSON数组

时间:2018-10-24 15:25:05

标签: arrays json sql-server tsql

在我们的SQL Server表中,我们有一个存储有字符串数组的json对象。我想以编程方式将该字符串分成几列。但是,即使有可能,我似乎也无法使其正常工作。

这是可能在WITH子句中创建多个列吗?还是在select语句中这样做更明智?

我整理了一些代码,以简化给出的内容。

示例JSON与{ "arr": ["str1 - str2"] }

类似
SELECT b.* FROM [table] a
OUTER APPLY
OPENJSON(a.value, '$.arr')
WITH
(
    strSplit1 VARCHAR(100) SPLIT('$.arr', '-',1),
    strSplit2 VARCHAR(100) SPLIT('$.arr', '-',2)
) b

2 个答案:

答案 0 :(得分:3)

由于标记[tsql]OPENJSON的使用,我认为这是SQL Server。但是可能是错误的……请始终指定您的RDBMS(带有版本)。

您的JSON有点奇怪...我想您为了简化起见而简化了它...

尝试一下:

DECLARE @tbl TABLE(ID INT IDENTITY,YourJSON NVARCHAR(MAX));
INSERT INTO @tbl VALUES(N'{ "arr": ["str1 - str2"] }') --weird example...
                      ,(N'{ "arr": ["a","b","c"] }');  --array with three elements

SELECT t.ID
      ,B.[value] AS arr
FROM @tbl t
CROSS APPLY OPENJSON(YourJSON) 
WITH(arr NVARCHAR(MAX) AS JSON) A
CROSS APPLY OPENJSON(A.arr) B;

一种相当简短的方法(但仅适合此简单示例):

SELECT t.ID
      ,A.*
FROM @tbl t
OUTER APPLY OPENJSON(JSON_QUERY(YourJSON,'$.arr')) A 

提示

JSON支持在SQL-Server 2016中引入

更新:如果JSON的内容是一个奇怪的CSV字符串...

有一个技巧可以将CSV转换为JSON数组。试试这个

DECLARE @tbl TABLE(ID INT IDENTITY,YourJSON NVARCHAR(MAX));
INSERT INTO @tbl VALUES(N'{ "arr": ["str1 - str2"] }') --weird example...
                      ,(N'{ "arr": ["a","b","c"] }')  --array with three elements
                      ,(N'{ "arr": ["x-y-z"] }');     --array with three elements in a weird CSV format

SELECT t.ID
      ,B.[value] AS arr
      ,C.[value]
FROM @tbl t
CROSS APPLY OPENJSON(YourJSON) 
WITH(arr NVARCHAR(MAX) AS JSON) A
CROSS APPLY OPENJSON(A.arr) B
CROSS APPLY OPENJSON('["' + REPLACE(B.[value],'-','","') + '"]') C;

OPENJSON('["' + REPLACE(B.[value],'-','","') + '"]')中的一些简单替换会从您的CSV字符串中创建一个JSON数组,可以在OPENJSON中打开它。

答案 1 :(得分:0)

我不知道有什么方法可以在JSON中拆分字符串。我想知道问题是否出在您的JSON中,它包含一个字符串而不是多个值?

下面的示例演示如何从数组中提取每个字符串;并且如果您想进一步分析并在连字符上拆分这些字符串,请说明如何使用SQL的常规SUBSTRING和CHARINDEX函数来完成此操作。

create table [table]
(
    value nvarchar(max)
)

insert [table](value)
values ('{ "arr": ["str1 - str2"] }'), ('{ "arr": ["1234 - 5678","abc - def"] }')

SELECT b.value
, rtrim(substring(b.value,1,charindex('-',b.value)-1))
, ltrim(substring(b.value,charindex('-',b.value)+1,len(b.value)))
FROM [table] a
OUTER APPLY OPENJSON(a.value, '$.arr') b

如果要将所有值都放在一个列中,则可以使用string_split函数:https://docs.microsoft.com/en-us/sql/t-sql/functions/string-split-transact-sql?view=sql-server-2017

SELECT ltrim(rtrim(c.value))
FROM [table] a
OUTER APPLY OPENJSON(a.value, '$.arr') b
OUTER APPLY STRING_SPLIT(b.value, '-') c