重命名MySQL中的重复行,WHERE IN() - 不能正常工作

时间:2015-01-20 21:05:58

标签: mysql sql rename where-in

我从这里开始: 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

似乎工作正常并返回像

这样的dubid行
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。那我怎么能让它发挥作用呢?另外如何为每一行nullyfy @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)

UPD 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或@last:= cf_vendlist是一个允许返回1或0(和)而不是cf_vendlist字符串的hack(请参阅下面的评论)

1 个答案:

答案 0 :(得分:0)

我在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

返回结果,如图。 1。

sorted data with reference id associated with each group

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上有一个索引。