Py学习  »  DATABASE

如何在MySQL中连接多个表时只更新“最近”的记录

Burton • 3 年前 • 1522 次点击  

这个问题在这个网站上被问了几个不同的方法,但我似乎不知道如何在这个特定的情况下实现更新。一般来说,我试图更新最新的 ContactNote Contact 那是属于一个 TeamId 并且有具体的 Categories .这是一个相当直接的数据库设置(见下图)。

我已经成功创建了一个“select子句”,它返回我想要更新的所有记录,但是当我添加 UPDATE 语言,MySQL给了我一个错误: Error Code: 1093. You can't specify target table 'cn1' for update in FROM clause

感谢您的指导。

工作选择子句

SELECT cn1.* from ContactNote cn1
    INNER JOIN Contact contact on contact.ContactId = cn1.ContactId
    INNER JOIN ContactCategory contactCategory on contactCategory.ContactId = contact.ContactId
    INNER JOIN Category category on category.CategoryId = contactCategory.CategoryId
    INNER JOIN ContactNote contactNote
        ON contactNote.ContactNoteId =
        (SELECT cn2.ContactNoteId
            FROM ContactNote cn2
            WHERE contact.ContactId = cn2.ContactId
            ORDER BY cn2.NoteDateTime DESC
            LIMIT 1
        )
where contact.TeamId = 1
    and contact.SpouseLastName = 'Rhodes'
    and category.`Name` in ('Sphere')
;

非工作更新子句

update ContactNote cn1
    INNER JOIN Contact contact on contact.ContactId = cn1.ContactId
    INNER JOIN ContactCategory contactCategory on contactCategory.ContactId = contact.ContactId
    INNER JOIN Category category on category.CategoryId = contactCategory.CategoryId
    INNER JOIN ContactNote contactNote
        ON contactNote.ContactNoteId =
        (SELECT cn2.ContactNoteId
            FROM ContactNote cn2
            WHERE contact.ContactId = cn2.ContactId
            ORDER BY cn2.NoteDateTime DESC
            LIMIT 1
        )
SET cn1.IsProspecting = b'1' 
where contact.TeamId = 1
    and contact.SpouseLastName = 'Rhodes'
    and category.`Name` in ('Sphere')
;

enter image description here

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/129360
文章 [ 1 ]  |  最新文章 3 年前
Bill Karwin
Reply   •   1 楼
Bill Karwin    3 年前

MySQL通常不喜欢在子查询中从表中选择并尝试在同一语句中更新它。

解决方法是连接到表,而不是在子查询中进行选择。我们正在寻找没有日期更大的匹配行的情况:

update ContactNote cn
    INNER JOIN Contact contact on contact.ContactId = cn.ContactId
    INNER JOIN ContactCategory contactCategory on contactCategory.ContactId = contact.ContactId
    INNER JOIN Category category on category.CategoryId = contactCategory.CategoryId
    LEFT OUTER JOIN ContactNote gt
        ON gt.ContactId = cn.ContactId AND gt.NodeDateTime > cn.NodeDateTime
SET cn.IsProspecting = b'1' 
WHERE contact.TeamId = 1
    AND contact.SpouseLastName = 'Rhodes'
    AND category.`Name` IN ('Sphere')
    AND gt.ContactId IS NULL -- meaning there is no note with a greater datetime
;

如果没有找到匹配的行,LEFT OUTER JOIN将为联接表的所有列返回NULL。如果条件试图查找具有更大NodeDateTime的注释,但未找到任何注释,则该行中的NodeDateTime cn 必须是相应CONTACT的最长(最近)日期时间。

这确实有一个缺点:如果最近一次有多张便笺?它将用更大的日期时间更新所有没有注释的注释,这可能会更新多个注释。这就是你想要的吗?