MySQL使用LEFT JOIN聚合函数

时间:2013-08-08 15:12:01

标签: mysql left-join aggregate-functions

这是星期五下午 * ,我的大脑已停止工作了。通常是我在回答这样愚蠢的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

我正在尝试获取符合WHERE jobs. ...条件的所有作业,如果他们有一个,则与该作业关联的最新type=complete注释的时间戳记:

Job ID     Complete Date
1          today
2          NULL
4          yesterday

作业3未显示,因为它不符合jobs.status条件。但我真正得到的是:

Job ID     Complete Date
1          today
4          yesterday

工作2缺失,即JOIN表现得像INNER JOIN 我确信这只是我有一个脑死亡的时刻,但我不明白为什么我的LEFT(OUTER)JOIN不会给我所有的工作,无论注释的价值如何。

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

*东部某处

1 个答案:

答案 0 :(得分:12)

由于您在notes子句中有WHERE表的过滤器,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;

这也可以使用子查询来完成,因此您可以在子查询中应用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