-2

我的表中有一个名称列表,如下所示:

paul-jones
Ron-Thomas
John-Doe
Michael-Adams
Jim-Jones
Adam-Jones
Bob-Thomas
Bill-Thomas

我想删除连字符后姓氏重复的所有行,但想为每个姓氏保留最旧的行。例如在上面的数据集中我想删除

    Jim-Jones
    Adam-Jones
    Bob-Thomas
    Bill-Thomas

并保持

paul-jones
Ron-Thomas
John-Doe
Michael-Adams 

等等。

我发现下面的查询可以像这样在连字符后提取所有字符, select SUBSTRING_INDEX(full_name,'-',-1) from names;但无法弄清楚如何使用这些值更新表中的 last_name 列,以便我可以使用此查询根据我的 last_name 列中的唯一值进行删除

("ALTER IGNORE TABLE names ADD UNIQUE (`last_name`)") ;

我希望这清楚地解释了我的问题。谢谢您的帮助。

4

2 回答 2

1

您不需要单独的 last_name 列(尽管使用名字和姓氏列而不是当前列将是一个好主意),您可以按原样删除:

create table names (id int not null primary key auto_increment, name varchar(63), order_column int not null);
insert into names (name,order_column) values ('Paul-Jones',1),('Ron-Thomas',2),('John-Doe',3),('Michael-Adams',4),('Jim-Jones',5),('Adam-Jones',6),('Bob-Thomas',7),('Bill-Thomas',8);
delete n2 from names n1
join names n2 on
    instr(n1.name,'-') and
    instr(n2.name,'-') and
    substring_index(n1.name,'-',-1)=substring_index(n2.name,'-',-1) and
    n2.id<>n1.id and
    n2.order_column>n1.order_column;

听起来您有一些日期或其他东西来识别最古老的记录;使用我有 order_column 的任何内容。

于 2020-09-07T18:34:52.210 回答
1

您可以SUBSTRING_INDEX在 UPDATE 查询中使用 更新last_name

UPDATE product
SET last_name = SUBSTRING_INDEX(supplier_reference,'-',-1)
WHERE SUBSTRING_INDEX(supplier_reference,'-',-1) != ''
AND last_name = '';

WHERE子句将确保仅当连字符后有值时查询才更新姓氏。

然后,如果你想删除重复的行但保留最旧的基于last_name

DELETE FROM product
WHERE id NOT IN (
    SELECT MIN(id)
    FROM product
    GROUP BY last_name
)

如果您有自动递增的值id,那么MIN(id)将确保保留最旧的记录。进行测试,而不是DELETE尝试SELECT * FROM product验证这些是否是您要删除的记录。

请注意,此查询还将删除last_name空的重复行。如果您不想这样,请WHERE last_name != ''在子查询中添加一个子句。

于 2020-09-07T18:08:56.860 回答