从SET字段中删除值的最佳方式?(The best way to remove value from

2019-07-19 03:06发布

这是更新一个MySQL SET领域的最佳途径,以去除该领域的特定值。

例如。 字段类别与价值:1,2,3,4,5? 我想从列表中删除“2”:

UPDATE table 
SET categories = REPLACE(categories, ',2,', ',') 
WHERE field LIKE '%,2,%';

但是,如果“2”是第一或从列表中最后一个值?

UPDATE table 
SET categories = REPLACE(categories, '2,', '') 
WHERE field LIKE '2,%';

UPDATE table 
SET categories = REPLACE(categories, ',2', '') 
WHERE field LIKE ',2%';

我怎么能处理所有3例为一个单一的查询?

Answer 1:

如果您需要从集中删除值不能超过一次以上存在,你可以这样做:

UPDATE yourtable
SET
  categories =
    TRIM(BOTH ',' FROM REPLACE(CONCAT(',', categories, ','), ',2,', ','))
WHERE
  FIND_IN_SET('2', categories)

看到它的工作在这里 。 如果该值可以比一次更存在,这将删除它的所有occourences:

UPDATE yourtable
SET
  categories =
    TRIM(BOTH ',' FROM
      REPLACE(
        REPLACE(CONCAT(',',REPLACE(col, ',', ',,'), ','),',2,', ''), ',,', ',')
    )
WHERE
  FIND_IN_SET('2', categories)


Answer 2:

update TABLE
set COLUMN = COLUMN & ~NUM
where COLUMN & NUM

:从评论部分采取http://dev.mysql.com/doc/refman/5.0/en/set.html

要小心的是,NUM是不是值“2”,但它的内部指标。 因此,如果你定义的字段,如“设置(1‘’2' ,‘3’,‘4’,‘5’)”,则这些值的对应的索引是(1,2,4,8,16)。



Answer 3:

最好的办法是不要保存通过餐桌上的逗号分隔值。

但是,为了回答你的问题,你可以使用CASE在此,

UPDATE table 
SET categories = CASE WHEN field LIKE '%,2,%'  -- In the middle
                           THEN REPLACE(categories, ',2,', ',')
                      WHEN field LIKE '2,%'    -- At the beginning
                           THEN REPLACE(categories, '2,', '')
                      WHEN field LIKE '%,2'    -- At the end
                           THEN REPLACE(categories, ',2', '') 
                      WHEN field = '2'         -- At whole
                           THEN '' 
                 END
WHERE FIND_IN_SET('2', categories)


Answer 4:

下面是这样做的另一种方式:

UPDATE table
SET categories = CONCAT_WS(',',
    IF(FIND_IN_SET('1', categories), '1', NULL),
    -- Note that '2' is missing here!
    IF(FIND_IN_SET('3', categories), '3', NULL),
    IF(FIND_IN_SET('4', categories), '4', NULL),
    IF(FIND_IN_SET('5', categories), '5', NULL)
);

CONCAT_WS会将其所有参数(除了参数1)的第一个参数(在这种情况下',' ),如果他们不NULL 。 我们寻求的每个可能值SET字段如果该字段包含,但跳过(我们要删除一个2在这种情况下)。 如果是的话,我们返回一个值,否则NULL 。 这样可以将集中所有的值用',' ,跳过我们想删除一个,重建了一个新的价值SET领域。

这当然只适用,如果你知道的所有可能值categories ,但由于这是一个SET场,你知道的。



Answer 5:

字段类别与价值:1,2,3,4,5? 我想从列表中删除“2”:

我发现,使用位运算符是最彻底的方法。 的返回值FIND_IN_SET()返回值的位置,以便您可以使用此计算中位关闭。

UPDATE table
SET categories = CAST(categories AS UNSIGNED) & ~POW(2, FIND_IN_SET('2', categories))
WHERE FIND_IN_SET('2', categories);

需要注意的是(categories+0)是对当前迫使SET值的整数。 您可能会发现这是多余的,但要小心包含大量的值集。 我发现所得的数学可能是错误的,如果你不明确强制设定为一个整数 - 你肯定执行这样的操作时不希望错误的值。



Answer 6:

我喜欢这种方式,通过克里斯·基伦( https://blog.krisgielen.be/archives/255 ):

UPDATE table SET categories =
  TRIM(BOTH ',' FROM REPLACE(CONCAT(',', categories, ','),
  CONCAT(',', '2', ','), ','))
WHERE ...

添加一个值来设定:

UPDATE table SET categories = 
  CONCAT_WS(',', categories, '2')
WHERE ...


文章来源: The best way to remove value from SET field?