从 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 表达式中使用 openjsonstring_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 中的子句)。
对于旧版本或单个值删除,替换方法可能是更好的选择。