在我的项目中,我有一个tasks
(id,name)表。我还有一个status_updates
(id,task_id,user_id,status,created_at)表。
我想选择最新status_update等于特定状态的任务。
我无法弄清楚如何结合以下内容:
使用GROUP_BY时,似乎1.和2.相互抵消。一个例子:
SELECT * FROM status_updates GROUP BY task_id ORDER created_at DESC
仅返回每个任务的最新status_update。 但是,这个:
SELECT * FROM status_updates WHERE status='1' GROUP BY task_id ORDER created_at DESC
执行ORDER之前的WHERE,从而从状态正确的中返回,而不是最新的,只返回状态正确的
我也尝试过使用HAVING,但由于它只适用于聚合列,我无法弄清楚如何正确使用它,或者它在这种情况下是否有用。
我正在使用Ruby on Rails,所以我想在MySQL和SQLite上都有答案。
答案 0 :(得分:3)
使用子查询:
SELECT
T.id,
T.name,
SU.status
FROM
Tasks T
INNER JOIN (SELECT task_id, MAX(created_at) AS max_created_at FROM Status_Updates GROUP BY task_id) SQ ON SQ.task_id = T.id
INNER JOIN Status_Updates SU ON
SU.task_id = SQ.task_id AND
SU.created_at = SQ.max_created_at
WHERE
SU.status = '1'
使用窗口函数和CTE(虽然目前RDBMS不支持,但它们很多,可能在将来)。这个有一个优点,它可以更好地处理关系:
WITH MyCTE AS
(
SELECT
T.id,
T.name,
SU.status,
ROW_NUMBER OVER(PARTITION BY T.id ORDER BY SU.created_at DESC, id DESC) AS row_num
FROM
Tasks T
INNER JOIN Status_Updates SU ON SU.task_id = T.id
)
SELECT
id,
name,
status
FROM
MyCTE
WHERE
row_num = 1