【问题标题】:Remove element from JSON array for whole table从整个表的 JSON 数组中删除元素
【发布时间】:2019-08-14 08:28:04
【问题描述】:

我有一列用 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')

有人知道删除所有 5 的快速/干净的方法吗?

我知道我可以使用多个替换来替换“,5]”、“[5”和“,5”,但似乎是一个混乱的解决方案。

【问题讨论】:

  • 什么版本的 SQL Server?
  • MS SQL Server 2017

标签: arrays json sql-server sql-server-2017


【解决方案1】:

不使用多个replace 的一种方法是在公用表表达式中使用openjsonstring_agg 来获取所需的值,然后更新连接到cte 的表。请注意,string_agg 在 2017 版或更高版本上受支持。

首先,创建并填充示例表(在您以后的问题中保存我们这一步):

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 Server 一起使用——即使是 2000 年以前的版本(我认为):

UPDATE @T 
SET Numbers = 
    REPLACE(
        REPLACE(
            REPLACE(Numbers, '[5,', '[')
        , ',5]', ']')
    , ',5,', '');

总之,如果您在 2017 年或更高版本上工作,并且需要从数组中删除多个值,cte + string_agg 方法可能会更容易(因为您所要做的就是更改 where 子句中的cte)。
对于旧版本,或者对于单个值的删除,替换方法可能是更好的选择。

【讨论】:

  • 谢谢。我会做一些测试,看看哪个最快。
  • 谢谢。这确实有助于解决我遇到的类似问题,不敢相信它是如此简单,我花了几个小时尝试复杂的解决方案
  • @Arun 我很高兴能帮上忙 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-29
  • 2022-01-23
  • 2017-05-19
  • 2017-05-17
相关资源
最近更新 更多