从SET字段中删除值的最佳方法是什么?

时间:2013-02-01 08:55:46

标签: mysql sql sql-update

更新mysql SET字段的最佳方法是从字段中删除特定值。

EG。字段类别的值: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个案例?!

6 个答案:

答案 0 :(得分:23)

如果您需要从集合中删除的值不能多次出现,您可以使用此功能:

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

看到它正常工作here。如果该值可以多次出现,则会删除它的所有内容:

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

答案 1 :(得分:6)

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

摘自http://dev.mysql.com/doc/refman/5.0/en/set.html

的评论部分

请注意,NUM不是值'2',而是其内部索引。因此,如果您将字段定义为“set('1,'2','3','4','5')”,则这些值的相应索引为(1,2,4,8,16)。

答案 2 :(得分:4)

最好的方法是不保存表格上用逗号分隔的值。

但是要回答你的问题,你可以使用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)

答案 3 :(得分:2)

这是另一种方法:

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的所有可能值时才有效,但由于这是一个index.aspx\getContactID字段,您知道这一点。

答案 4 :(得分:0)

  

具有值的字段类别: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值强制为整数。您可能会发现这是多余的,但请注意包含大量值的集合。我发现如果你没有明确地强制设置为整数,结果数学可能是错误的 - 在执行这样的操作时你肯定不想要错误的值。

答案 5 :(得分:0)

我喜欢Kris Gielen(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 ...