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

标签 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

似乎工作正常并返回像这样的可疑行

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');

更新

我们得到了

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 是一个 hack,它允许返回 1 或 0(and) 而不是 cf_vendlist 字符串(见下面我的评论)

最佳答案

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

关于mysql - 重命名 MySQL 中的重复行,WHERE IN () - 不能正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28055126/

相关文章:

mysql select inner join with limit

c# - 重命名服务器目录中的图像文件

android - 批量重命名文件 - Android Studio

sql - 如何为 SQL Server 表中的所有行返回 XML 列中特定属性的值?

sql - 比较 postgres 中的数组

linux - 无法重命名文件名

php - 如何获取mysql列名和值

mysql - 无法连接到 osx 上 docker 内的 mysql

php - 如何一次性使用SQL在SQL中运行多个插入查询?

mysql - SQL查询最后连续相同的数据