【问题标题】:Change field when duplicate [duplicate]重复时更改字段[重复]
【发布时间】:2012-09-12 03:08:27
【问题描述】:

可能重复:
Renaming the duplicate data in sql

我必须清理一个表字段(article_title),创建一个新字段,其中重复的标题被更改为:

 id  |      title         |     new_title
 34  | My Duplicate Title | My Duplicate Title
 ...
 95  | My Duplicate Title | My Duplicate Title (2)

我使用了这个mysql查询,但是它不起作用(所有等级都是1):

 SET @rank := 0;

 SET @prev := NULL;

 SELECT @rank := IF(@prev = title, @rank + 1, 1) AS rank,
   id, IF(@rank>1, Concat(title, ' (', @rank, ')'), title), @prev := title
 FROM articles ORDER BY title ASC

我做错了什么?

【问题讨论】:

  • 如果你有一个唯一的ID(或另一个唯一的字段),那么你可以设置括号(2),(3)等中的数字作为具有相同标题但较小的 ID:
  • 第二个可能的副本包含基于存储过程的(长)解决方案。但是,我想知道为什么不能仅使用变量进行此查询和/或如果我在解决方案中遗漏了某些内容...

标签: mysql


【解决方案1】:

我认为这是你最好只通过 Python 或 PHP 或其他任何方式与数据库交谈并用传统编程语言而不是 SQL 实现你的逻辑的时候。

以前看到的标题的哈希表/字典(我只是使用原始标题作为键,看到的次数作为值)将使这很容易。

Python 伪实现:

# c and c2 are db.cursor() object
c.execute('select id, title from books')
seen = {}
for b in c:
  if seen.has_key(b[1]):
    seen[b[1]] += 1
    c.execute('update books set new_title = %s where id = %d',(b[1]+' ('+str(seen[b[1]])+')'))
  else:
    seen[b[1]] = 1

需要添加一些数据库连接代码,也许是一些事务提交等。但这会给你这个想法。

【讨论】:

  • -1 OP 没有指定任何服务器端语言。我觉得答案应该保留在数据库中,同时建议使用服务器端替代方案。
  • 适合工作的工具。我认为它不值得被否决。我提出了一个可行的解决方案,甚至提供了代码。我的意思是,您也可以使用触发器在纯 SQL 中纠正 CMS,但您到底为什么要这样做?
  • 我想到了一个python脚本,但是我只能通过phpMyAdmin访问这个远程db,并且我需要定期执行这个查询。我先尝试 SQL,因为使用 python 我必须在本地数据库中复制表,执行脚本,然后上传更改。
  • 虽然它增加了额外的难度,但您可以从 PhpMyAdmin 中导出 csv,然后让 python 脚本逐行读取该脚本,而不是让它实际运行更新查询,而是它会编写一个包含必要更新的文本文件,然后您可以在 PhpMyAdmin 中将其作为批量加​​载运行。
【解决方案2】:
drop table if exists t;
drop table if exists t2;
create table t( id integer ,title varchar(50), new_title varchar(50));
insert into t (id, title) values (34, 'My Duplicate Title'), (95, 'My Duplicate Title');
create temporary table t2 (id integer, new_title varchar(50));
insert into t2 (id, new_title)
select id, concat( title, 
  ' (', 
    (select count(*) from t as tt where tt.title = t.title and tt.id > t.id), 
    ')' 
) from t;
update t, t2
set t.new_title = t2.new_title where t.id=t2.id;

【讨论】:

  • 这仅在我手动插入各种重复的子集时才有效......还是我遗漏了什么?
  • 不,这显示了一个测试用例。它适用于重复的标题,以“创建临时表...”开头将“t”替换为“article_title”作为表名并将其应用于您的案例。
  • 如何在临时表中自动插入重复的标题?
  • 这就是 INSERT 语句的作用。 “自动”是什么意思?
  • 我需要先选择(并排名)重复项。我需要知道哪些是重复的,并使用它们的增量 id 对它们进行“排名”(例如,第一个副本的排名为 1,第二个为 2,依此类推)。如果我有这个,我可以使用你的 INSERT 语句。
猜你喜欢
  • 1970-01-01
  • 2016-06-16
  • 1970-01-01
  • 2018-11-07
  • 1970-01-01
  • 2012-02-15
  • 2019-01-21
  • 2012-12-14
  • 1970-01-01
相关资源
最近更新 更多