在根据一列对该表进行排序的同时更新另一个表中的一个表

Yan*_*Chi 6 mysql order-by update

这是我试图在 MySQL 中找出的问题。我们有一个旧表,其中包含我们用户提交的一些表单。不知何故,之前的决定是每次用户参与此调查时,都会提交一个新表单。因此,在旧表中,我们很容易有几行具有相同的名字和姓氏,但其他列中的值不同,并且还有一个时间戳列 Date_Submission。

现在我们正在尝试将所有内容移动到一个新表中,但这一次,对于每个人,我们只保留一行。我们希望保留该用户的一些最新旧数据(如电子邮件、电话号码等)

我可以执行以下操作:

update newtable, oldtable set newtable.email = oldtable.email where newtable.firstname = oldtable.firstname and newtable.lastname = oldtable.lastname;

显然,这不会给我每个人的“最新”旧日期。

所以我尝试了这个:

update newtable, oldtable set newtable.email = oldtable.email where newtable.firstname = oldtable.firstname and newtable.lastname = oldtable.lastname 按 oldtable.Date_Submission 顺序;

但是他们 MySQL 会抱怨:

“错误 1221 (HY000):UPDATE 和 ORDER BY 的错误使用”。

所以我想知道,实现这一目标的正确方法是什么?

Rol*_*DBA 4

有两种选择:

  1. 重复密钥更新时插入...

    INSERT INTO newtable
    SELECT * FROM oldtable
    ORDER BY tmstamp_value
    ON DUPLICATE KEY UPDATE email=VALUES(email), address=VALUES(address) 
    ... ;
    
    Run Code Online (Sandbox Code Playgroud)
  2. 替换成

    REPLACE INTO newtable
    SELECT * FROM oldtable
    ORDER BY tmstamp_value;
    
    Run Code Online (Sandbox Code Playgroud)

    它机械地执行删除和插入。

警告

请注意,我将其应用于ORDER BY旧表。这应该有助于获取给定姓氏、名字的最新数据。

您还应该UNIQUE INDEX在新表上添加一个,如下所示:

ALTER TABLE newtable ADD UNIQUE INDEX name_ndx (lastname,firstname);
Run Code Online (Sandbox Code Playgroud)

如果您正在进行更新,有两种方法可以执行此操作:

  1. 更新加入

    UPDATE
    (SELECT lastname,firstname,phone,email
    FROM oldtable ORDER BY lastname,firstname) A
    LEFT JOIN newtable B USING (lastname,firstname)
    SET B.phone=A.phone,B.email=A.email;
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用 GROUP BY 更新 JOIN

    UPDATE
    (
        SELECT BB.id,BB.phone,BB.email FROM 
        (SELECT lastname,firstname,MAX(id) id FROM oldtable GROUP BY lastname,firstname) AA
        INNER JOIN oldtable BB USING (lastname,firstname)
    ) A INNER JOIN newtable B USING (id)
    SET B.phone=A.phone,B.email=A.email;
    
    Run Code Online (Sandbox Code Playgroud)

这两个选项都将充分利用UNIQUE名称索引。