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 日期更新内部联接的主要内容,如果未能解决你的问题,请参考以下文章