我有两个表,其中一个表包含引用另一个表的记录:
Goal
id (int)
name (text)
value_mask (text)
GoalStatus
id (int)
goal (int)
created (datetime)
value (text)
Goal.id == GoalStatus.goal
我想做的是,从GoalStatus表中为目标中的每条记录提取最新记录。目前,我知道如何执行此操作的唯一方法是对Goal(伪代码)中的每条记录单独进行查询:
goals = db.query("SELECT * FROM Goal")
foreach (goals as goal):
goalStatus = db.query("
SELECT * FROM GoalStatus
WHERE goal = " + goal.id + "
ORDER BY created DESC
LIMIT 1
")
有没有一种方法可以解决这个问题,所以我不会对每个目标进行额外的查询?
答案 0 :(得分:1)
select
g.*,
gs.id GoalStatusID,
gs.created,
gs.value
from
goal g inner join goalstatus gs
on g.id = gs.goal
where
gs.created in
( select max( gs2.created )
from goalstatus gs2
where g.id = gs2.goal )
答案 1 :(得分:1)
这是每组最大的问题。这是一件非常普遍的事情,想要做到这一点,SQL并不容易,所以它会被问到很多。
Here's a summary您可以采取的方法。它们将具有不同的性能属性,并且当有两行与最大值共享相同的值时,它们的行为会有所不同。
作为默认的第一种方法,我倾向于使用null-left-join而不是子查询:
SELECT ...
FROM Goal
JOIN GoalStatus AS Gs0 ON Gs0.goal=Goal.id
LEFT JOIN GoalStatus AS Gs1 ON Gs1.goal=Goal.id AND Gs1.created>Gs0.created
WHERE Goal.id=(someid)
AND Gs1.id IS NULL
也就是说,连接没有其他行具有更大created
值的行。
答案 2 :(得分:0)
您可以加入GoalStatus,其中没有其他具有相同目标ID且具有更长创建日期的目标状态。
SELECT *
FROM Goal
INNER JOIN GoalStatus on Goal.GoalId=GoalStatus.GoalId
WHERE Not Exists(SELECT *
FROM GoalStatus innerGs
WHERE innerGs.GoalId=Goal.GoalId
and innerGs.created > GoalStatus.created)
非常丑陋,可能表现不佳,但我能想到的只有。