重命名 MySQL 中的重复行,WHERE IT () - 无法正常工作
Rename duplicate rows in MySQL, WHERE IN () - dosen't works fine
我从这里开始:
Rename duplicate rows in MySQL
SELECT mid(s,instr(s,',')+1) as dubid
FROM (
SELECT group_concat(id ORDER BY id ASC) s, count(*) c
FROM `...`
GROUP BY field
HAVING c > 1) as z
似乎工作正常并且 returns 像
这样的可疑行
1
3,5,6
8
10,15
所以我做了这个:
set @suf:=0;
UPDATE `table_cf_vendlist`
SET `cf_vendlist` = concat(`cf_vendlist`, ' \(', @suf:=@suf+1,'\)')
WHERE `cf_vendlistid` IN ({SELECT mid...})
但它只重命名每行的第一个 ID。那么我怎样才能让它发挥作用呢?另外如何为每一行取消@suf 计数器?
没有 PHP。仅MySQL!
set @suf:=0;
set @last := 0;
UPDATE `vtiger_cf_vendlist` t1
INNER JOIN (
SELECT MIN(cf_vendlistid) as id, cf_vendlist
FROM vtiger_cf_vendlist
GROUP BY cf_vendlist) AS unique1
ON (t1.cf_vendlist = unique1.cf_vendlist)
SET t1.`cf_vendlist` = concat(t1.`cf_vendlist`, ' \(',
@suf := if (@last = t1.cf_vendlistid, @suf+1, 1 and @last := t1.cf_vendlist), '\)')
WHERE t1.cf_vendlistid <> unique1.id
但我不确定 t1.cf_vendlist
在哪里,unique1.cf_vendlist
在哪里。名称中的结果也是 0 和 1,每个 id 集没有递增和归零。但是,仍然需要重命名。
这是 运行 的一些数据 sqlfiddle.com:
CREATE TABLE IF NOT EXISTS `table_cf_vendlist` (
`cf_vendlistid` int(11) NOT NULL AUTO_INCREMENT,
`cf_vendlist` varchar(200) NOT NULL,
PRIMARY KEY (`cf_vendlistid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=78 ;
INSERT INTO `table_cf_vendlist` (`cf_vendlistid`, `cf_vendlist`) VALUES
(2, 'Поставщик 2'),
(3, 'Поставщик 3'),
(4, 'Поставщик 4'),
(5, 'del 1'),
(6, 'Поставщик 1 (1)'),
(7, 'Поставщик 1 (2)'),
(8, 'пост 66'),
(9, 'пост 77'),
(10, 'пост 67'),
(11, 'пост 5'),
(12, '123'),
(13, '102'),
(14, 'пост 5 (1)'),
(15, 'пост 70'),
(47, 'Поставщик 1'),
(48, 'Поставщик 2'),
(49, 'Поставщик 3'),
(50, 'Поставщик 4'),
(51, 'del 1'),
(52, 'Поставщик 1'),
(53, 'Поставщик 1'),
(54, 'пост 5'),
(55, '124523452346256456'),
(56, 'пост 66'),
(57, 'пост 77'),
(58, 'пост 5'),
(59, 'пост 5'),
(60, 'пост 5'),
(61, 'пост 67'),
(62, '123'),
(63, '123'),
(64, '123'),
(65, 'пост 5'),
(66, 'пост 68'),
(67, '123'),
(68, '123'),
(69, '123'),
(70, '123'),
(71, '102'),
(72, 'пост 5'),
(73, 'пост 70');
UPD
我们得到了
52 Поставщик 1 (11)
53 Поставщик 1 (12)
而不是
52 Поставщик 1 (3)
53 Поставщик 1 (4)
和
48 Поставщик 2 (13)
49 Поставщик 3 (14)
50 Поставщик 4 (15)
而不是
48 Поставщик 2 (2)
49 Поставщик 3 (2)
50 Поставщик 4 (2)
更新 2:
set @suf:=0;
set @last := 0;
UPDATE table_cf_vendlist t
INNER JOIN (SELECT cf_vendlistid, concat(cf_vendlist, ' (',
@suf := if (STRCMP(@last1, cf_vendlist) = 0,
@suf+1,
1 or @last := cf_vendlist), ')') as new_label
FROM (
SELECT t1.cf_vendlistid, t1.cf_vendlist, unique1.id as reference_id
FROM table_cf_vendlist t1
INNER JOIN (SELECT MIN(cf_vendlistid) as id, cf_vendlist
FROM table_cf_vendlist
GROUP BY cf_vendlist) AS unique1
ON t1.cf_vendlist = unique1.cf_vendlist
ORDER BY cf_vendlist, cf_vendlistid
) AS t1_sorted
WHERE t1_sorted.cf_vendlistid <> t1_sorted.reference_id)
AS t1_sorted_labeled
ON t.cf_vendlistid = t1_sorted_labeled.cf_vendlistid
SET t.cf_vendlist = t1_sorted_labeled.new_label;
有效。但是 1 or @last := cf_vendlist 是一个允许 return 1 or 0(and) 而不是 cf_vendlist
字符串的 hack(见下面我的评论)
我在 sqlfiddle 中有一个解决方案。要了解它的工作原理,
1)看子查询t1_sorted
SELECT t1.cf_vendlistid, t1.cf_vendlist, unique1.id as reference_id
FROM table_cf_vendlist t1
INNER JOIN (SELECT MIN(cf_vendlistid) as id, cf_vendlist
FROM table_cf_vendlist
GROUP BY cf_vendlist) AS unique1
ON t1.cf_vendlist = unique1.cf_vendlist
WHERE t1.cf_vendlistid <> unique1.id
ORDER BY cf_vendlist, cf_vendlistid
其中 returns 结果如图所示。 1.
2a) 在子查询 t1_sorted_labeled 中,结果预计会删除每个组中第一次出现的 cf_vendlist 和
2b) 使用 cf_vendlist 和(拷贝数)
创建了一个额外字段 new_label
3) 最后,原始查询在 UPDATE 语句中与此子查询连接,它只是将 new_label 复制到 cf_vendlist
因此,完整答案:
set @suf:=0;
set @last := 0;
UPDATE table_cf_vendlist t
INNER JOIN (SELECT cf_vendlistid, concat(cf_vendlist, ' (',
@suf := if (STRCMP(@last, cf_vendlist) = 0,
@suf+1,
1 and length(@last := cf_vendlist)), ')') as new_label
FROM (
SELECT t1.cf_vendlistid, t1.cf_vendlist, unique1.id as reference_id
FROM table_cf_vendlist t1
INNER JOIN (SELECT MIN(cf_vendlistid) as id, cf_vendlist
FROM table_cf_vendlist
GROUP BY cf_vendlist) AS unique1
ON t1.cf_vendlist = unique1.cf_vendlist
ORDER BY cf_vendlist, cf_vendlistid
) AS t1_sorted
WHERE t1_sorted.cf_vendlistid <> t1_sorted.reference_id)
AS t1_sorted_labeled
ON t.cf_vendlistid = t1_sorted_labeled.cf_vendlistid
SET t.cf_vendlist = t1_sorted_labeled.new_label;
顺便说一句,你真的应该在 cf_vendlist 上有一个索引。
我从这里开始: Rename duplicate rows in MySQL
SELECT mid(s,instr(s,',')+1) as dubid
FROM (
SELECT group_concat(id ORDER BY id ASC) s, count(*) c
FROM `...`
GROUP BY field
HAVING c > 1) as z
似乎工作正常并且 returns 像
这样的可疑行1
3,5,6
8
10,15
所以我做了这个:
set @suf:=0;
UPDATE `table_cf_vendlist`
SET `cf_vendlist` = concat(`cf_vendlist`, ' \(', @suf:=@suf+1,'\)')
WHERE `cf_vendlistid` IN ({SELECT mid...})
但它只重命名每行的第一个 ID。那么我怎样才能让它发挥作用呢?另外如何为每一行取消@suf 计数器? 没有 PHP。仅MySQL!
set @suf:=0;
set @last := 0;
UPDATE `vtiger_cf_vendlist` t1
INNER JOIN (
SELECT MIN(cf_vendlistid) as id, cf_vendlist
FROM vtiger_cf_vendlist
GROUP BY cf_vendlist) AS unique1
ON (t1.cf_vendlist = unique1.cf_vendlist)
SET t1.`cf_vendlist` = concat(t1.`cf_vendlist`, ' \(',
@suf := if (@last = t1.cf_vendlistid, @suf+1, 1 and @last := t1.cf_vendlist), '\)')
WHERE t1.cf_vendlistid <> unique1.id
但我不确定 t1.cf_vendlist
在哪里,unique1.cf_vendlist
在哪里。名称中的结果也是 0 和 1,每个 id 集没有递增和归零。但是,仍然需要重命名。
这是 运行 的一些数据 sqlfiddle.com:
CREATE TABLE IF NOT EXISTS `table_cf_vendlist` (
`cf_vendlistid` int(11) NOT NULL AUTO_INCREMENT,
`cf_vendlist` varchar(200) NOT NULL,
PRIMARY KEY (`cf_vendlistid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=78 ;
INSERT INTO `table_cf_vendlist` (`cf_vendlistid`, `cf_vendlist`) VALUES
(2, 'Поставщик 2'),
(3, 'Поставщик 3'),
(4, 'Поставщик 4'),
(5, 'del 1'),
(6, 'Поставщик 1 (1)'),
(7, 'Поставщик 1 (2)'),
(8, 'пост 66'),
(9, 'пост 77'),
(10, 'пост 67'),
(11, 'пост 5'),
(12, '123'),
(13, '102'),
(14, 'пост 5 (1)'),
(15, 'пост 70'),
(47, 'Поставщик 1'),
(48, 'Поставщик 2'),
(49, 'Поставщик 3'),
(50, 'Поставщик 4'),
(51, 'del 1'),
(52, 'Поставщик 1'),
(53, 'Поставщик 1'),
(54, 'пост 5'),
(55, '124523452346256456'),
(56, 'пост 66'),
(57, 'пост 77'),
(58, 'пост 5'),
(59, 'пост 5'),
(60, 'пост 5'),
(61, 'пост 67'),
(62, '123'),
(63, '123'),
(64, '123'),
(65, 'пост 5'),
(66, 'пост 68'),
(67, '123'),
(68, '123'),
(69, '123'),
(70, '123'),
(71, '102'),
(72, 'пост 5'),
(73, 'пост 70');
UPD
我们得到了
52 Поставщик 1 (11)
53 Поставщик 1 (12)
而不是
52 Поставщик 1 (3)
53 Поставщик 1 (4)
和
48 Поставщик 2 (13)
49 Поставщик 3 (14)
50 Поставщик 4 (15)
而不是
48 Поставщик 2 (2)
49 Поставщик 3 (2)
50 Поставщик 4 (2)
更新 2:
set @suf:=0;
set @last := 0;
UPDATE table_cf_vendlist t
INNER JOIN (SELECT cf_vendlistid, concat(cf_vendlist, ' (',
@suf := if (STRCMP(@last1, cf_vendlist) = 0,
@suf+1,
1 or @last := cf_vendlist), ')') as new_label
FROM (
SELECT t1.cf_vendlistid, t1.cf_vendlist, unique1.id as reference_id
FROM table_cf_vendlist t1
INNER JOIN (SELECT MIN(cf_vendlistid) as id, cf_vendlist
FROM table_cf_vendlist
GROUP BY cf_vendlist) AS unique1
ON t1.cf_vendlist = unique1.cf_vendlist
ORDER BY cf_vendlist, cf_vendlistid
) AS t1_sorted
WHERE t1_sorted.cf_vendlistid <> t1_sorted.reference_id)
AS t1_sorted_labeled
ON t.cf_vendlistid = t1_sorted_labeled.cf_vendlistid
SET t.cf_vendlist = t1_sorted_labeled.new_label;
有效。但是 1 or @last := cf_vendlist 是一个允许 return 1 or 0(and) 而不是 cf_vendlist
字符串的 hack(见下面我的评论)
我在 sqlfiddle 中有一个解决方案。要了解它的工作原理,
1)看子查询t1_sorted
SELECT t1.cf_vendlistid, t1.cf_vendlist, unique1.id as reference_id
FROM table_cf_vendlist t1
INNER JOIN (SELECT MIN(cf_vendlistid) as id, cf_vendlist
FROM table_cf_vendlist
GROUP BY cf_vendlist) AS unique1
ON t1.cf_vendlist = unique1.cf_vendlist
WHERE t1.cf_vendlistid <> unique1.id
ORDER BY cf_vendlist, cf_vendlistid
其中 returns 结果如图所示。 1.
2a) 在子查询 t1_sorted_labeled 中,结果预计会删除每个组中第一次出现的 cf_vendlist 和
2b) 使用 cf_vendlist 和(拷贝数)
创建了一个额外字段 new_label3) 最后,原始查询在 UPDATE 语句中与此子查询连接,它只是将 new_label 复制到 cf_vendlist
因此,完整答案:
set @suf:=0;
set @last := 0;
UPDATE table_cf_vendlist t
INNER JOIN (SELECT cf_vendlistid, concat(cf_vendlist, ' (',
@suf := if (STRCMP(@last, cf_vendlist) = 0,
@suf+1,
1 and length(@last := cf_vendlist)), ')') as new_label
FROM (
SELECT t1.cf_vendlistid, t1.cf_vendlist, unique1.id as reference_id
FROM table_cf_vendlist t1
INNER JOIN (SELECT MIN(cf_vendlistid) as id, cf_vendlist
FROM table_cf_vendlist
GROUP BY cf_vendlist) AS unique1
ON t1.cf_vendlist = unique1.cf_vendlist
ORDER BY cf_vendlist, cf_vendlistid
) AS t1_sorted
WHERE t1_sorted.cf_vendlistid <> t1_sorted.reference_id)
AS t1_sorted_labeled
ON t.cf_vendlistid = t1_sorted_labeled.cf_vendlistid
SET t.cf_vendlist = t1_sorted_labeled.new_label;
顺便说一句,你真的应该在 cf_vendlist 上有一个索引。