我在列中有以下json:
{
"fields":[
{
"field":"modelName",
"value":"abc123"
},
{
"field":"displayName",
"value":"ABC 123"
},
{
"field":"order",
"value":5
}
],
"variables":[
{
"varId":4,
"oldValue":100,
"newValue":"150"
},
{
"varId":5,
"oldValue":"abc",
"newValue":"def"
}
]
}
我想将此信息提取为以下内容:
Id Field Value VarId oldValue newValue
2 modelName abc123 null null null
2 displayName ABC 123 null null null
2 order 5 null null null
2 null null 4 100 150
2 null null 5 abc def
这样,我就可以遍历结果集并进行空检查以查看其类型。
我目前有以下说法:
select Id, Fields.Field, Fields.Value, Variables.VarId, Variables.OldValue, Variables.NewValue from Product
cross apply openjson( data, '$.fields') with (Field varchar(50) '$.field', Value varchar(50) '$.value') AS Fields
cross apply openjson( data, '$.variables') with (VarId int '$.varId', OldValue varchar(50) '$.oldValue', NewValue varchar(50) '$.newValue') AS Variables
但这给了我以下输出:
如您所见,所有内容都是重复的。可以得到我想要的输出吗?
谢谢
答案 0 :(得分:2)
您需要将其作为2个单独的解析进行。这使用FULL OUTER JOIN
和(公认的)哑ON
子句。您还可以使用UNION ALL
和NULL
中没有列的值:
CREATE TABLE dbo.Product (ID int,
[data] nvarchar(MAX));
DECLARE @JSON nvarchar(MAX) = N'{
"fields":[
{
"field":"modelName",
"value":"abc123"
},
{
"field":"displayName",
"value":"ABC 123"
},
{
"field":"order",
"value":5
}
],
"variables":[
{
"varId":4,
"oldValue":100,
"newValue":"150"
},
{
"varId":5,
"oldValue":"abc",
"newValue":"def"
}
]
}';
INSERT INTO dbo.Product (ID,
[data])
VALUES(2,@JSON);
GO
WITH Fields AS(
SELECT P.Id,
F.Field,
F.Value,
FROM Product P
CROSS APPLY OPENJSON(data, '$.fields')
WITH (Field varchar(50) '$.field',
[Value] varchar(50) '$.value') F),
Variables AS(
SELECT P.Id,
V.VarId,
V.OldValue,
V.NewValue
FROM Product P
CROSS APPLY OPENJSON(data, '$.variables')
WITH (VarId int '$.varId',
OldValue varchar(50) '$.oldValue',
NewValue varchar(50) '$.newValue') V)
SELECT ISNULL(F.ID,V.ID) AS ID,
F.Field,
F.[Value],
V.VarId,
V.OldValue,
V.NewValue
FROM Fields F
FULL OUTER JOIN Variables V ON 1 = 2; --Dumb ON clause is Dumb
答案 1 :(得分:1)
这只是另一种可能的方法(感谢@Larnu提供测试数据)。当然,您需要分别解析fields
和variables
部分,但是可以将OPENJSON()
与一个显式模式(WITH
子句)一起使用:
表格:
CREATE TABLE Product (
ID int,
[data] nvarchar(MAX)
);
DECLARE @json nvarchar(MAX) = N'{
"fields":[
{
"field":"modelName",
"value":"abc123"
},
{
"field":"displayName",
"value":"ABC 123"
},
{
"field":"order",
"value":5
}
],
"variables":[
{
"varId":4,
"oldValue":100,
"newValue":"150"
},
{
"varId":5,
"oldValue":"abc",
"newValue":"def"
}
]
}';
INSERT INTO Product (ID, [data])
VALUES
(1, @json),
(2, @json),
(3, @json)
声明:
SELECT p.ID, j.*
FROM Product p
CROSS APPLY (
SELECT *
FROM OPENJSON (p.data, '$.fields') WITH (
field varchar(100) '$.field',
value varchar(100) '$.value',
varId int '$.varId',
oldValue varchar(100) '$.oldValue',
newValue varchar(100) '$.newValue'
)
UNION ALL
SELECT *
FROM OPENJSON (p.data, '$.variables') WITH (
field varchar(100) '$.field',
value varchar(100) '$.value',
varId int '$.varId',
oldValue varchar(100) '$.oldValue',
newValue varchar(100) '$.newValue'
)
) j
-- Additional WHERE clause
--WHERE p.ID = 2