MySQL 使用 MAX 日期更新内部联接

Posted

技术标签:

【中文标题】MySQL 使用 MAX 日期更新内部联接【英文标题】:MySQL Update inner Join with MAX Date 【发布时间】:2021-12-02 06:50:33 【问题描述】:

mysql 8.0 中,我有两个具有以下结构的表:

Table1 :Child
ChildId | EnrolmentId | EnrolmentStatus

Table 2 : Enrolment
EnrolmentId | EnrolmentStatus | DateUpdated    

我正在尝试通过使用下面的 TSQL 加入 Enrollment 表来更新子表中 EnromentStatus 的值:

UPDATE child
INNER JOIN enrolment ON child.enrolmentid= enrolment.enrolmentid
SET child.EnrolmentStatus = enrolment.enrolmentstatus 
WHERE child.enrolmentid = enrolment.enrolmentid;

问题是 Enrollment 有多个子注册条目,因此我需要执行 MAX(DateUpdated) 来获取一条记录以将状态更新为最新状态,但我不能只获得一条记录。

【问题讨论】:

是否只需要使用内连接?不能使用嵌套查询吗? 我不太记得是哪个,但我认为您可以根据“选择前 1....最近的日期。为含糊而道歉,目前工作中有很多事情要做。希望这会有所帮助。 @groovy_guy 只要我可以使用嵌套查询获取最新记录,就不需要内部连接。我已经尝试过了,但它也不喜欢它: UPDATE child AS c JOIN (SELECT MAX(lastUpdatedDateTime), ccs.enrolmentid, ccs.arrangementStartDate,ccs.arrangementEndDate,ccs.status FROM ccsenrolment ccs WHERE c.EnrolmentId = ccs.enrolmentID ) a SET c.enrolmentstatus = a.status, c.enrolmentsStartDate = a.arrangementstartdate, c.enrolmentEndDate = a.arrangementenddate; 请包括每个表格的样本数据。至少对我而言,您的描述表明您的表结构可能需要调整。如果每个子行有多个 Enrollment 行,它建议我 Enrollment 表中的 EnrolmentId 应该是主键,并且应该有一个外键返回到 Child 表。样本数据将有助于澄清这一点。对不起,如果我叫错了树。 【参考方案1】:

试试这样的, 这只是一个简单的嵌套查询,无需使用INNER JOIN,即可一次性更新所有孩子的状态。

UPDATE  child
    SET child.enrolmentstatus= (
        SELECT enrolment.enrolmentstatus
        FROM enrolmentstatus
        WHERE child.enrolmentid = enrolment.enrolmentid
        ORDER BY DateUpdated DESC
        LIMIT 1
    )

【讨论】:

效果很好,我只需要添加 LIMIT 1 否则它会抱怨子查询中有多个行。 @snowflakes74 是的,让我为其他人更新查询中的限制,以防有人发现它有用【参考方案2】:

如果您的 Enrollment 表在一段时间内跟踪 EnrolmentStatus,那么它会 似乎两个表之间的当前关系是错误的。

CREATE TABLE Child (
    ChildId TINYINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    EnrolmentStatus VARCHAR(20) NOT NULL
);

CREATE TABLE EnrolmentStatusLog (
    EnrolmentStatusLogId TINYINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    ChildId TINYINT UNSIGNED NOT NULL,
    EnrolmentStatus VARCHAR(20) NOT NULL,
    DateUpdated DATETIME NOT NULL
);

那么@groovy_guy 提出的查询只需要更改连接

UPDATE  Child
    SET Child.EnrolmentStatus= (
        SELECT EnrolmentStatusLog.EnrolmentStatus
        FROM EnrolmentStatusLog
        WHERE Child.ChildId = EnrolmentStatusLog.ChildId
        ORDER BY DateUpdated DESC
        LIMIT 1
    );

如果上述关于结构的假设是正确的,您可以通过直接更改 Child.EnrolmentStatus 并使用触发器填充 EnrolmentStatusLog 来取消此查询

【讨论】:

以上是关于MySQL 使用 MAX 日期更新内部联接的主要内容,如果未能解决你的问题,请参考以下文章

在 Oracle 上使用内部联接更新语句

使用内部联接更新多个表中的列

日期范围内的 Oracle sql 内部联接

无法使用简单的内部联接更新表

带有内部联接的 Oracle 更新语句

带有内部联接的 SQL Server 更新