如何用mysql删除列中的特殊字符?

kupeojn6  于 2021-06-15  发布在  Mysql
关注(0)|答案(3)|浏览(307)

我参加了一个项目,遇到别人设计不好,我们有一个表叫task,每个任务有很多用户,任务表如下:

+----------------+---------------+------+-----+---------+-------+
| Field          | Type          | Null | Key | Default | Extra |
+----------------+---------------+------+-----+---------+-------+
| id             | varchar(40)   | NO   | PRI | NULL    |       |
| name           | varchar(100)  | YES  |     | NULL    |       |
| task_users     | varchar(1000) | YES  |     | NULL    |       |

用户的存储方式如下 aaa,bbb,ccctask_users 列,这意味着许多用户id放在一个列中,我知道这是一个非常糟糕的设计,但由于它是一个老项目,我不能修改表的设计。
现在我有一个问题,如果用户被删除了,我怎么才能把它从数据库中删除呢 task_users 列?
用户id由uuid生成,长度固定,有32个字符,因此每个用户id都是唯一的,例如 40cf5f01eb2f4d2c954412f27b3bf6eb ,但问题是,用户id可能会出现在服务器的任何位置 task_users 列,所以我不知道如何删除它

aaa,40cf5f01eb2f4d2c954412f27b3bf6eb,bbb -- in center
40cf5f01eb2f4d2c954412f27b3bf6eb,aaa,bbb -- in head
aaa,bbb,40cf5f01eb2f4d2c954412f27b3bf6eb -- in end

当删除用户id时,更新的结果如下

aaa,bbb

我想知道我们是否可以使用一个更新sql来删除指定的用户id,并保持相同的数据格式?
note:i am 在一个mysql存储过程中做这件事,额外的变量可能会有帮助,但我还是想用一个sql来做,mysql版本是5.0
提前谢谢!

sshcrbum

sshcrbum1#

可以使用以下表达式将指定的用户标识符替换为空字符串:

SET @userID = '40cf5f01eb2f4d2c954412f27b3bf6eb';

UPDATE `task`
SET task_users = REGEXP_REPLACE(task_users, CONCAT('(,', @userID, '|', @userID, ',?)'), '');

或添加 WHERE 筛选要更新的记录的子句:

UPDATE `task`
SET task_users = REGEXP_REPLACE(task_users, CONCAT('(,', @userID, '|', @userID, ',?)'), '');
WHERE task_users RLIKE CONCAT('(^|,)', @userID,'(,|$)')

请注意 REGEXP_REPLACE() 函数是在mysql 8.0中添加的。

l7mqbcuq

l7mqbcuq2#

试试这个 CASE 表达式在哪里 uid 是存储过程的参数。。。

UPDATE `task` SET `task_users` = CASE
  -- at the start
  WHEN `task_users` LIKE CONCAT(uid, ',%')
    THEN REPLACE(`task_users`, CONCAT(uid, ','), '')
  -- at the end
  WHEN `task_users` LIKE CONCAT('%,', uid)
    THEN REPLACE(`task_users`, CONCAT(',', uid), '')
  -- in the middle
  WHEN `task_users` LIKE CONCAT('%,', uid, ',%')
    THEN REPLACE(`task_users`, CONCAT(',', uid, ','), ',')
  -- only that user
  ELSE ''
END
WHERE `task_users` LIKE CONCAT('%', uid, '%');

演示~http://sqlfiddle.com/#!9月1日2月1日
原“四问”答案如下

-- only that user
UPDATE `task`
SET `task_users` = ''
WHERE `task_users` = uid;

-- at start
UPDATE `task`
SET `task_users` = REPLACE(`task_users`, CONCAT(uid, ','), '')
WHERE `task_users` LIKE CONCAT(uid, ',%');

-- at end
UPDATE `task`
SET `task_users` = REPLACE(`task_users`, CONCAT(',', uid), '')
WHERE `task_users` LIKE CONCAT('%,', uid);

-- in the middle
UPDATE `task`
SET `task_users` = REPLACE(`task_users`, CONCAT(',', uid, ','), ',')
WHERE `task_users` LIKE CONCAT('%,', uid, ',%');

演示~http://sqlfiddle.com/#!9/8e9b9bb/1号

ecr0jaav

ecr0jaav3#

我想我们可以通过一个查询:

UPDATE yourTable
SET task_users = SUBSTRING(
    REPLACE(CONCAT(',', task_users, ','), CONCAT(',', uid, ','), ','),
    2,
    LENGTH(task_users) - LENGTH(uid) - 1)
WHERE task_users REGEXP CONCAT('[[:<:]]', uid, '[[:>:]]');


以下是演示的链接(仅用于测试目的):

演示

这个答案使用了一个技巧,我们在单词的开头和结尾加上逗号 task_users 字符串。然后,我们通过在一个给定的用户id的开始和结束处添加逗号来比较它。如果找到匹配项,我们只替换为一个逗号。但是,这使得替换仍保留其起始和结束逗号,因此我们使用子字符串操作删除这些逗号。
撇开sql不谈,希望您能从这些答案的复杂性中看出,在sql数据库中处理csv数据可能是一个真正令人头痛的问题。也许你甚至可以用这个页面来证明你的同事,表的设计需要改变。

相关问题