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

时间:2019-01-10 04:16:20

标签: mysql sql mysql-5.0

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

+----------------+---------------+------+-----+---------+-------+
| 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,ccc一样存储在task_users列中,这意味着许多用户ID放在一列中,我知道这是一个非常糟糕的设计,但是由于它是一个旧项目,所以我不能修改表格设计。

现在我有问题,如果删除了用户,如何将其从task_users列中删除?

用户ID是由UUID生成的,并且具有32个字符的固定长度,因此每个用户ID都是唯一的,例如40cf5f01eb2f4d2c954412f27b3bf6eb,但是问题在于用户ID可能会在{ {1}}列,因此我不知道如何删除它

task_users

删除用户ID时,更新结果就像

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

我想知道我们可以使用一个更新sql删除指定的用户ID并仍然保持相同的数据格式吗?

注意:我正在MySQL存储过程中执行此操作,附加变量可能会有所帮助,但我仍想仅使用一个sql进行操作,MySQL版本为 5.0

谢谢!

3 个答案:

答案 0 :(得分:4)

我认为我们可以通过一个查询来做到这一点:

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, '[[:>:]]');

enter image description here

这里是演示的链接(仅用于测试目的):

Demo

此答案使用了一个技巧,通过该技巧我们将逗号添加到task_users字符串的开头和结尾。然后,我们还通过在逗号的开头和结尾处加上逗号来比较给定的用户ID。如果找到匹配项,我们将只替换一个逗号。但是,这将使替换仍然保留其开始和结束逗号,因此我们将其替换为带有子字符串的操作。

除了SQL奥林匹克竞赛之外,希望您能从这些答案的复杂性中看到,在SQL数据库中使用CSV数据可能确实令人头疼。也许您甚至可以将此页面用作向同事证明餐桌设计需要更改的证据。

答案 1 :(得分:2)

尝试使用此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/1d2baa/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

答案 2 :(得分:2)

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

I tensorflow/core/grappler/devices.cc:53] Number of eligible GPUs (core count >= 8): 0 (Note: TensorFlow was not compiled with CUDA support)
I tensorflow/core/grappler/clusters/single_machine.cc:359] Starting new session
E tensorflow/core/grappler/grappler_item_builder.cc:636] Init node dense/kernel/Assign doesn't exist in graph

或添加SET @userID = '40cf5f01eb2f4d2c954412f27b3bf6eb'; UPDATE `task` SET task_users = REGEXP_REPLACE(task_users, CONCAT('(,', @userID, '|', @userID, ',?)'), ''); 子句以过滤记录以进行更新:

WHERE

注意,在MySQL 8.0中添加了REGEXP_REPLACE()函数。