根据父记录查找最新的子记录(有条件)
Find Latest Child Record (With Conditions) Per Parent Record
我有 2 个具有 parent/child 层次结构的表,我正在尝试为每个父记录提取最新子记录的 ID,而且还对正在提取的子记录应用了条件。
这是我的表格的样子:
-----------
| Quizzes |
-----------
| ID |
-----------
| 1 |
| 2 |
| 3 |
-----------
-------------------------------------
| QuizAttempts |
-------------------------------------
| ID | QuizID | AttemptedAt |
-------------------------------------
| 1 | 1 | 2021-01-01 05:00:00 |
| 2 | 1 | 2021-01-01 08:30:00 |
| 3 | 2 | 2021-01-01 05:00:00 |
| 4 | 3 | 2021-01-01 07:00:00 |
| 5 | 3 | 2021-02-01 07:00:00 |
| 6 | 3 | 2021-03-01 07:00:00 |
-------------------------------------
现在,假设我想为从 2021-01-01 00:00:00
到 2021-01-01 23:59:59
尝试的每个 Quiz
提取最新 QuizAttempt
的 ID,看起来像这样:
------------------------------------------------
| QuizID | QuizAttemptID | AttemptedAt |
------------------------------------------------
| 1 | 2 | 2020-01-01 08:30:00 |
| 2 | 3 | 2020-01-01 05:00:00 |
| 3 | 4 | 2020-01-01 07:00:00 |
------------------------------------------------
目前,我正在做一个自引用连接来比较 ID 以提取最新的 QC:
SELECT attempts1.ID
FROM QuizAttempts AS attempts1
LEFT OUTER JOIN QuizAttempts AS attempts2
ON (attempts1.QuizID = attempts2.QuizID
AND attempts1.ID < attempts2.ID)
WHERE attempts2.ID IS NULL;
这适用于拉取最新的子记录。但是,当我添加日期范围条件时(比如添加 attempts1.AttemptedAt BETWEEN '2021-01-01 00:00:00' AND '2021-01-01 23:59:59'
),我得到的结果是空的。
我建议在子查询中使用 window 函数:
SELECT qa.*
FROM (SELECT qa.*,
ROW_NUMBER() OVER (PARTITION BY QuizID ORDER BY id DESC) as seqnum
FROM QuizAttempts qa
WHERE qa.attemptedat >= '2021-01-01' AND
qa.attemptedat < '2021-01-02'
) qa
WHERE seqnum = 1;
请注意,日期运算更简单,无需处理时间分量。
编辑:
您还可以使用相关子查询:
SELECT qa.*
FROM QuizAttempts qa
WHERE qa.id = (SELECT MAX(qa2.id),
FROM QuizAttempts qa2
WHERE qa2.QuizID = qa.QuizID AND
qa2.attemptedat >= '2021-01-01' AND
qa2.attemptedat < '2021-01-02'
) qa;
我有 2 个具有 parent/child 层次结构的表,我正在尝试为每个父记录提取最新子记录的 ID,而且还对正在提取的子记录应用了条件。
这是我的表格的样子:
-----------
| Quizzes |
-----------
| ID |
-----------
| 1 |
| 2 |
| 3 |
-----------
-------------------------------------
| QuizAttempts |
-------------------------------------
| ID | QuizID | AttemptedAt |
-------------------------------------
| 1 | 1 | 2021-01-01 05:00:00 |
| 2 | 1 | 2021-01-01 08:30:00 |
| 3 | 2 | 2021-01-01 05:00:00 |
| 4 | 3 | 2021-01-01 07:00:00 |
| 5 | 3 | 2021-02-01 07:00:00 |
| 6 | 3 | 2021-03-01 07:00:00 |
-------------------------------------
现在,假设我想为从 2021-01-01 00:00:00
到 2021-01-01 23:59:59
尝试的每个 Quiz
提取最新 QuizAttempt
的 ID,看起来像这样:
------------------------------------------------
| QuizID | QuizAttemptID | AttemptedAt |
------------------------------------------------
| 1 | 2 | 2020-01-01 08:30:00 |
| 2 | 3 | 2020-01-01 05:00:00 |
| 3 | 4 | 2020-01-01 07:00:00 |
------------------------------------------------
目前,我正在做一个自引用连接来比较 ID 以提取最新的 QC:
SELECT attempts1.ID
FROM QuizAttempts AS attempts1
LEFT OUTER JOIN QuizAttempts AS attempts2
ON (attempts1.QuizID = attempts2.QuizID
AND attempts1.ID < attempts2.ID)
WHERE attempts2.ID IS NULL;
这适用于拉取最新的子记录。但是,当我添加日期范围条件时(比如添加 attempts1.AttemptedAt BETWEEN '2021-01-01 00:00:00' AND '2021-01-01 23:59:59'
),我得到的结果是空的。
我建议在子查询中使用 window 函数:
SELECT qa.*
FROM (SELECT qa.*,
ROW_NUMBER() OVER (PARTITION BY QuizID ORDER BY id DESC) as seqnum
FROM QuizAttempts qa
WHERE qa.attemptedat >= '2021-01-01' AND
qa.attemptedat < '2021-01-02'
) qa
WHERE seqnum = 1;
请注意,日期运算更简单,无需处理时间分量。
编辑:
您还可以使用相关子查询:
SELECT qa.*
FROM QuizAttempts qa
WHERE qa.id = (SELECT MAX(qa2.id),
FROM QuizAttempts qa2
WHERE qa2.QuizID = qa.QuizID AND
qa2.attemptedat >= '2021-01-01' AND
qa2.attemptedat < '2021-01-02'
) qa;