从 JSON 数组中删除整个 table 的元素
Remove element from JSON array for whole table
我有一列填充了 JSON 个数组。看起来像:
Numbers
'[1,33,5,4,5]'
'[1,2,555,4,5]'
'[1,5,3,4,5]'
'[1,25,3,4,5]'
'[1,2,5,4,5]'
'[1,2,3,4,55]'
我想删除 5 的所有实例(不是 55、555 或 25)所以它看起来像
Numbers
'[1,33,4]'
'[1,2,555,4]'
'[1,5,3,4]'
'[1,25,3,4]'
'[1,2,4]'
'[1,2,3,4,55]'
我有全文索引,所以我可以使用以下方法识别包含它的行
包含(数字,'5')
有谁知道 quick/clean 删除所有 5 的方法吗?
我知道我可以使用多个替换来替换“,5]”、“[5”和“,5,”,但似乎是一个混乱的解决方案。
没有多个 replace
的一种方法是在公共 table 表达式中使用 openjson
和 string_agg
来获取所需的值,然后更新table 加入了 cte。请注意,2017 版或更高版本支持 string_agg
。
首先,创建并填充示例 table(请在您以后的问题中为我们省去这一步):
DECLARE @T AS TABLE
(
Numbers varchar(50)
)
INSERT INTO @T(Numbers) VALUES
('[1,33,5,4,5]'),
('[1,2,555,4,5]'),
('[1,5,3,4,5]'),
('[1,25,3,4,5]'),
('[1,2,5,4,5]'),
('[1,2,3,4,55]');
cte:
WITH CTE AS
(
SELECT Numbers, '[' + string_agg([Value], ',') +']' As NewNumbers
FROM @T
CROSS APPLY
(SELECT [Value] FROM OPENJSON(Numbers)) As x
WHERE [Value] != 5
GROUP BY Numbers
)
更新:
UPDATE T
SET Numbers = NewNumbers
FROM @T As T
JOIN CTE ON T.Numbers = CTE.Numbers
验证:
SELECT *
FROM @T
结果:
Numbers
[1,33,4]
[1,2,555,4]
[1,3,4]
[1,25,3,4]
[1,2,4]
[1,2,3,4,55]
您可以在 DB<>Fiddle 上看到演示。
但是,替换选项要短得多,并且可以与任何版本的 SQL 服务器一起使用 - 即使是 2000 年(我认为):
UPDATE @T
SET Numbers =
REPLACE(
REPLACE(
REPLACE(Numbers, '[5,', '[')
, ',5]', ']')
, ',5,', '');
总而言之,如果您在 2017 年或更高版本上工作,并且需要从数组中删除多个值,则 cte + string_agg 方法可能会更容易(因为您所要做的就是更改where
cte 中的子句)。
对于旧版本或单个值删除,替换方法可能是更好的选择。
我有一列填充了 JSON 个数组。看起来像:
Numbers
'[1,33,5,4,5]'
'[1,2,555,4,5]'
'[1,5,3,4,5]'
'[1,25,3,4,5]'
'[1,2,5,4,5]'
'[1,2,3,4,55]'
我想删除 5 的所有实例(不是 55、555 或 25)所以它看起来像
Numbers
'[1,33,4]'
'[1,2,555,4]'
'[1,5,3,4]'
'[1,25,3,4]'
'[1,2,4]'
'[1,2,3,4,55]'
我有全文索引,所以我可以使用以下方法识别包含它的行 包含(数字,'5')
有谁知道 quick/clean 删除所有 5 的方法吗?
我知道我可以使用多个替换来替换“,5]”、“[5”和“,5,”,但似乎是一个混乱的解决方案。
没有多个 replace
的一种方法是在公共 table 表达式中使用 openjson
和 string_agg
来获取所需的值,然后更新table 加入了 cte。请注意,2017 版或更高版本支持 string_agg
。
首先,创建并填充示例 table(请在您以后的问题中为我们省去这一步):
DECLARE @T AS TABLE
(
Numbers varchar(50)
)
INSERT INTO @T(Numbers) VALUES
('[1,33,5,4,5]'),
('[1,2,555,4,5]'),
('[1,5,3,4,5]'),
('[1,25,3,4,5]'),
('[1,2,5,4,5]'),
('[1,2,3,4,55]');
cte:
WITH CTE AS
(
SELECT Numbers, '[' + string_agg([Value], ',') +']' As NewNumbers
FROM @T
CROSS APPLY
(SELECT [Value] FROM OPENJSON(Numbers)) As x
WHERE [Value] != 5
GROUP BY Numbers
)
更新:
UPDATE T
SET Numbers = NewNumbers
FROM @T As T
JOIN CTE ON T.Numbers = CTE.Numbers
验证:
SELECT *
FROM @T
结果:
Numbers
[1,33,4]
[1,2,555,4]
[1,3,4]
[1,25,3,4]
[1,2,4]
[1,2,3,4,55]
您可以在 DB<>Fiddle 上看到演示。
但是,替换选项要短得多,并且可以与任何版本的 SQL 服务器一起使用 - 即使是 2000 年(我认为):
UPDATE @T
SET Numbers =
REPLACE(
REPLACE(
REPLACE(Numbers, '[5,', '[')
, ',5]', ']')
, ',5,', '');
总而言之,如果您在 2017 年或更高版本上工作,并且需要从数组中删除多个值,则 cte + string_agg 方法可能会更容易(因为您所要做的就是更改where
cte 中的子句)。
对于旧版本或单个值删除,替换方法可能是更好的选择。