MySQL使用LEFT JOIN聚合函数

Nic*_*nks 6 mysql aggregate-functions left-join

现在是星期五下午*,我的大脑已停止工作了.通常是我在回答这样愚蠢的SQL问题,对不起!

我试图获得一个表,以及另一个表的列的最高值,通过LEFT JOIN将后者加入前者.

SELECT
  jobs.*,
  MAX(notes.`timestamp`) AS complete_date
FROM jobs
LEFT JOIN notes ON (jobs.id=notes.job_id)
WHERE (jobs.status="complete" OR jobs.status="closed")
  AND (notes.type="complete" OR notes.type IS NULL)
GROUP BY jobs.id
ORDER BY complete_date ASC
Run Code Online (Sandbox Code Playgroud)

我正在尝试获得符合...标准的所有工作,WHERE jobs.如果他们有一个,那么type=complete与该工作相关的最新注释的时间戳:

Job ID     Complete Date
1          today
2          NULL
4          yesterday
Run Code Online (Sandbox Code Playgroud)

作业3不会出现,因为它不符合jobs.status标准.但我真正得到的是:

Job ID     Complete Date
1          today
4          yesterday
Run Code Online (Sandbox Code Playgroud)

缺少作业2,即JOIN的作用类似于INNER JOIN.
我确信这只是我有一个脑死亡的时刻,但我不明白为什么我的LEFT(OUTER)JOIN不会给我所有的工作,无论注意的价值.

具体来说,用户可以删除备注,因此可能完整/已关闭的作业可能没有type=complete备注(当状态更改时输入备注),我试图抓住用户关闭作业的情况,添加备注,然后删除笔记.

*在东方的某个地方

Tar*_*ryn 14

由于您notesWHERE子句中JOIN具有表的过滤器INNER JOIN,因此将其移动到以下JOIN条件:

SELECT
  jobs.*,
  MAX(notes.`timestamp`) AS complete_date
FROM jobs
LEFT JOIN notes 
  ON (jobs.id=notes.job_id)
  AND (notes.type="complete" OR notes.type IS NULL)
WHERE (jobs.status="complete" OR jobs.status="closed")
GROUP BY jobs.id
ORDER BY complete_date ASC;
Run Code Online (Sandbox Code Playgroud)

这也可以使用子查询来完成,因此您可以在子查询中应用notes过滤器:

SELECT
  jobs.*,
  n.complete_date
FROM jobs
LEFT JOIN
(
    select job_id, MAX(`timestamp`) AS complete_date
    from notes 
    where (type="complete" OR type IS NULL)
    group by job_id
) n
  ON (jobs.id=n.job_id)
WHERE (jobs.status="complete" OR jobs.status="closed")
ORDER BY complete_date ASC
Run Code Online (Sandbox Code Playgroud)