假设我们有一个简单的博客文章表,例如:
aid title content
1 Foo Lorem Ips…
2 Bar Dolor Sit…
3 Boo Amet Cons…
...还有另一个评论表:
cid aid name comment date
1 1 zaphod First! 1404294939
2 1 arthur Not you again!!111 1404296182
3 1 marvin It’s all useless anyw… 1404299811
现在我想生成一份包含相应文章最新评论的所有文章的列表。这意味着我必须离开加入articles
表上的comments
表,但是对于每个文章行,我只希望评论行具有最高date
值或换句话说:只有我为每篇文章评论连接ORDER BY date DESC LIMIT 1
做第一行。
最好(或最简单)的方法是什么?
答案 0 :(得分:3)
您只能使用联接来执行此操作。它比Sub查询快得多。
select articles.*,comments1.* from
Articles articles
LEFT JOIN (Comments comments1
LEFT JOIN Comments comments2 on comments1.date<comments2.date
and comments1.aid=comments2.aid
) on comments2.cid IS NULL and comments1.aid=articles.aid;
SQLFiddle示例:http://sqlfiddle.com/#!2/51a5bb/4
答案 1 :(得分:1)
所需的方法是首先找到每篇文章的最新评论日期:
SELECT aid, MAX(Date) AS Date
FROM Comments
GROUP BY aid;
然后,您可以将此逻辑放在子查询中,并使用aid
和date
联接回到评论,以获取所有字段:
SELECT c.*
FROM Comments AS c
INNER JOIN
( SELECT aid, MAX(Date) AS Date
FROM Comments
GROUP BY aid
) AS mc
ON mc.aid = c.aid
AND mc.Date = c.Date;
然后,您可以在“约会”表格中添加联接。如果所有文章都有评论,或者您只想要带有评论的文章,那么您可以使用:
SELECT *
FROM Articles AS a
INNER JOIN Comments AS c
ON c.Aid = a.aid
INNER JOIN
( SELECT aid, MAX(Date) AS Date
FROM Comments
GROUP BY aid
) AS mc
ON mc.aid = c.aid
AND mc.Date = c.Date;
如果不是,您将需要使用带括号的LEFT JOIN来确保子查询上的INNER JOIN
不会删除没有注释的文章:
SELECT *
FROM Articles AS a
LEFT JOIN (Comments AS c
INNER JOIN
( SELECT aid, MAX(Date) AS Date
FROM Comments
GROUP BY aid
) AS mc
ON mc.aid = c.aid
AND mc.Date = c.Date)
ON c.Aid = a.aid;
<强> Example on SQL Fiddle 强>
这实际上只是简写:
SELECT *
FROM Articles AS a
LEFT JOIN
( SELECT c.*
FROM Comments AS c
INNER JOIN
( SELECT aid, MAX(Date) AS Date
FROM Comments
GROUP BY aid
) AS mc
ON mc.aid = c.aid
AND mc.Date = c.Date
) AS c
ON c.Aid = a.aid;
但是,由于MySQL实现了所有子查询,这避免了Comments
的无法实现的实现。这两个查询中的Comparing the execution plans表明前者会表现得更好。
答案 2 :(得分:0)
使用group by语句查找每篇文章的最后评论日期。使用它来加入文章和最后评论。
select a.*, c.*
from articles a
join
(
select aid, max(date) as date
from comments
group by aid
) last_comment on (last_comment.aid = a.aid)
join comments c on (c.aid = last_comment.aid and c.date = last_comment.date);
答案 3 :(得分:0)
select title,contents,name,coment from articles join comment
using(aid) where date =(select max(date) from comment group by aid);