MS Sql 服务器 OPENJSON 功能出现问题
Having trouble with MS Sql Server OPENJSON feature
我在下面为这个问题创建了一个 sql 测试脚本。
IF OBJECT_ID('tempdb..#temp') IS NOT NULL
DROP TABLE #temp;
CREATE TABLE #temp
(
Id INT NOT NULL PRIMARY KEY
, Attributes NVARCHAR(MAX) NULL
);
INSERT INTO #temp (Id, Attributes)
VALUES (1, '[{"Name":"Step","Value":"A"},{"Name":"State","Value":"Active"}]');
INSERT INTO #temp (Id, Attributes)
VALUES (2, '[{"Name":"Step","Value":"B"},{"Name":"State","Value":"Inactive"}]');
INSERT INTO #temp (Id, Attributes)
VALUES (3, '[{"Name":"State","Value":"Active"}]');
INSERT INTO #temp (Id, Attributes)
VALUES (4, '[{"Name":"Step","Value":"D"}]');
SELECT
t.Id
, t.Attributes
, stepname.Value AS [Step]
, statename.Value AS [State]
FROM #temp t
CROSS APPLY
OPENJSON(t.Attributes)
WITH
(
Name NVARCHAR(MAX) '$.Name'
, Value NVARCHAR(MAX) '$.Value'
) AS stepname
CROSS APPLY
OPENJSON(t.Attributes)
WITH
(
Name NVARCHAR(MAX) '$.Name'
, Value NVARCHAR(MAX) '$.Value'
) AS statename
WHERE 1 = 1
--AND (stepname.Name = statename.Name) -- A
--AND -- B
--( -- B
-- stepname.Name IS NULL -- B
-- OR stepname.Name = 'Step' -- B
--) -- B
--AND -- B
--( -- B
-- statename.Name IS NULL -- B
-- OR statename.Name = 'State' -- B
--); -- B
运行 该脚本按原样给出以下输出:
编号
属性
步骤
州
1
[{"Name":"Step","Value":"A"},{"Name":"State","Value":"Active"}]
一个
一个
1
[{"Name":"Step","Value":"A"},{"Name":"State","Value":"Active"}]
一个
有效
1
[{"Name":"Step","Value":"A"},{"Name":"State","Value":"Active"}]
有效
一个
1
[{"Name":"Step","Value":"A"},{"Name":"State","Value":"Active"}]
有效
有效
2
[{"Name":"Step","Value":"B"},{"Name":"State","Value":"Inactive"}]
B
B
2
[{"Name":"Step","Value":"B"},{"Name":"State","Value":"Inactive"}]
B
无效
2
[{"Name":"Step","Value":"B"},{"Name":"State","Value":"Inactive"}]
无效
B
2
[{"Name":"Step","Value":"B"},{"Name":"State","Value":"Inactive"}]
无效
无效
3
[{"名称":"状态","值":"有效"}]
有效
有效
4
[{"名称":"步骤","值":"D"}]
D
D
虽然我希望在输出中看到只有 4 行,每个数据行一行。
编号
属性
步骤
州
1
[{"Name":"Step","Value":"A"},{"Name":"State","Value":"Active"}]
一个
有效
2
[{"Name":"Step","Value":"B"},{"Name":"State","Value":"Inactive"}]
B
无效
3
[{"名称":"状态","值":"有效"}]
有效
4
[{"名称":"步骤","值":"D"}]
D
我在我的示例中留下了一些注释代码,以查看我尝试过但都无济于事的事情类型。用 '-- A' 取消注释 where 语句让我更接近,但不完全。我确信取消注释 where 子句中末尾带有“-- B”的语句会给我想要的东西,但事实并非如此。关于如何做到这一点有什么想法吗?
我最初只有 1 个 OPENJSON 块,但没有成功,所以我认为也许有 2 个 OPENJSON 块,一个用于 Step,一个用于 State 会有所帮助,但仍然无法包含第 3 行和第 4 行数据,因为这些行中的每一行都缺少 2 个 JSON 值之一。
非常感谢您的帮助!
可以使用条件聚合:
SELECT
t.Id
, t.Attributes
, [Step] = MAX(CASE WHEN stepname.Name = 'Step' THEN stepname.Value END)
, [State] = MAX(CASE WHEN statename.Name = 'State' THEN statename.Value END)
FROM #temp t
CROSS APPLY OPENJSON(t.Attributes) WITH (
Name NVARCHAR(MAX) '$.Name'
, Value NVARCHAR(MAX) '$.Value'
) AS stepname
CROSS APPLY OPENJSON(t.Attributes) WITH (
Name NVARCHAR(MAX) '$.Name'
, Value NVARCHAR(MAX) '$.Value'
) AS statename
GROUP BY t.Id, t.Attributes
ORDER BY t.Id;
我在下面为这个问题创建了一个 sql 测试脚本。
IF OBJECT_ID('tempdb..#temp') IS NOT NULL
DROP TABLE #temp;
CREATE TABLE #temp
(
Id INT NOT NULL PRIMARY KEY
, Attributes NVARCHAR(MAX) NULL
);
INSERT INTO #temp (Id, Attributes)
VALUES (1, '[{"Name":"Step","Value":"A"},{"Name":"State","Value":"Active"}]');
INSERT INTO #temp (Id, Attributes)
VALUES (2, '[{"Name":"Step","Value":"B"},{"Name":"State","Value":"Inactive"}]');
INSERT INTO #temp (Id, Attributes)
VALUES (3, '[{"Name":"State","Value":"Active"}]');
INSERT INTO #temp (Id, Attributes)
VALUES (4, '[{"Name":"Step","Value":"D"}]');
SELECT
t.Id
, t.Attributes
, stepname.Value AS [Step]
, statename.Value AS [State]
FROM #temp t
CROSS APPLY
OPENJSON(t.Attributes)
WITH
(
Name NVARCHAR(MAX) '$.Name'
, Value NVARCHAR(MAX) '$.Value'
) AS stepname
CROSS APPLY
OPENJSON(t.Attributes)
WITH
(
Name NVARCHAR(MAX) '$.Name'
, Value NVARCHAR(MAX) '$.Value'
) AS statename
WHERE 1 = 1
--AND (stepname.Name = statename.Name) -- A
--AND -- B
--( -- B
-- stepname.Name IS NULL -- B
-- OR stepname.Name = 'Step' -- B
--) -- B
--AND -- B
--( -- B
-- statename.Name IS NULL -- B
-- OR statename.Name = 'State' -- B
--); -- B
运行 该脚本按原样给出以下输出:
编号 | 属性 | 步骤 | 州 |
---|---|---|---|
1 | [{"Name":"Step","Value":"A"},{"Name":"State","Value":"Active"}] | 一个 | 一个 |
1 | [{"Name":"Step","Value":"A"},{"Name":"State","Value":"Active"}] | 一个 | 有效 |
1 | [{"Name":"Step","Value":"A"},{"Name":"State","Value":"Active"}] | 有效 | 一个 |
1 | [{"Name":"Step","Value":"A"},{"Name":"State","Value":"Active"}] | 有效 | 有效 |
2 | [{"Name":"Step","Value":"B"},{"Name":"State","Value":"Inactive"}] | B | B |
2 | [{"Name":"Step","Value":"B"},{"Name":"State","Value":"Inactive"}] | B | 无效 |
2 | [{"Name":"Step","Value":"B"},{"Name":"State","Value":"Inactive"}] | 无效 | B |
2 | [{"Name":"Step","Value":"B"},{"Name":"State","Value":"Inactive"}] | 无效 | 无效 |
3 | [{"名称":"状态","值":"有效"}] | 有效 | 有效 |
4 | [{"名称":"步骤","值":"D"}] | D | D |
虽然我希望在输出中看到只有 4 行,每个数据行一行。
编号 | 属性 | 步骤 | 州 |
---|---|---|---|
1 | [{"Name":"Step","Value":"A"},{"Name":"State","Value":"Active"}] | 一个 | 有效 |
2 | [{"Name":"Step","Value":"B"},{"Name":"State","Value":"Inactive"}] | B | 无效 |
3 | [{"名称":"状态","值":"有效"}] | 有效 | |
4 | [{"名称":"步骤","值":"D"}] | D |
我在我的示例中留下了一些注释代码,以查看我尝试过但都无济于事的事情类型。用 '-- A' 取消注释 where 语句让我更接近,但不完全。我确信取消注释 where 子句中末尾带有“-- B”的语句会给我想要的东西,但事实并非如此。关于如何做到这一点有什么想法吗?
我最初只有 1 个 OPENJSON 块,但没有成功,所以我认为也许有 2 个 OPENJSON 块,一个用于 Step,一个用于 State 会有所帮助,但仍然无法包含第 3 行和第 4 行数据,因为这些行中的每一行都缺少 2 个 JSON 值之一。
非常感谢您的帮助!
可以使用条件聚合:
SELECT
t.Id
, t.Attributes
, [Step] = MAX(CASE WHEN stepname.Name = 'Step' THEN stepname.Value END)
, [State] = MAX(CASE WHEN statename.Name = 'State' THEN statename.Value END)
FROM #temp t
CROSS APPLY OPENJSON(t.Attributes) WITH (
Name NVARCHAR(MAX) '$.Name'
, Value NVARCHAR(MAX) '$.Value'
) AS stepname
CROSS APPLY OPENJSON(t.Attributes) WITH (
Name NVARCHAR(MAX) '$.Name'
, Value NVARCHAR(MAX) '$.Value'
) AS statename
GROUP BY t.Id, t.Attributes
ORDER BY t.Id;