2014-07-02 95 views
0

說我們有博客文章的一個簡單的表格,例如:MySQL的加入左行僅在第一個右排

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 

現在我想用相應文章的最新評論來生成所有文章的列表。這意味着我必須在comments表中將articles表加入表中,但對於每篇文章行,我只希望具有最高值date的評論行,換言之:只有第一行時,我爲每篇文章評論連接做ORDER BY date DESC LIMIT 1

要做到這一點,最好的(或者最簡單的)方法是什麼?

回答

1

所需的方法是,首先找到每篇文章的最新評論日期:

SELECT aid, MAX(Date) AS Date 
FROM Comments 
GROUP BY aid; 

然後,您可以把這個邏輯的子查詢中,並使用aiddate讓所有的領域攜手回評論:

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顯示前者會表現更好。

0

找到每篇文章的最後評論日期與一組聲明。用它來加入文章和最後的評論。

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

你可以使用連接來做到這一點,它比Sub查詢快得多。 SQLFiddle的

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; 

實施例:http://sqlfiddle.com/#!2/51a5bb/4

0
select title,contents,name,coment from articles join comment 
using(aid) where date =(select max(date) from comment group by aid);