MYSQL JOIN所有子行并仅显示父行一次

时间:2013-01-25 21:05:54

标签: php mysql sql database join

我有一个简单的文章和评论系统,包含以下表格:

文章表:

id | writer | text
 1 | Bob    | first article
 2 | Marley | second article

评论表:

id | article_id | comment
 1 |      1     |  i love this article
 2 |      1     |  good one
 3 |      2     |  waiting for more

我想选择每篇文章及其评论。我使用以下查询:

SELECT * FROM articles LEFT JOIN comments ON articles.id = comments.article_id 

我得到的结果:

 articles.id   | articles.writer | articles.text  | comments.id | comments.article_id | comments.comment
 1             | Bob             | first article  |    1        |         1           | i love this article
 1             | Bob             | first article  |    2        |         1           | good one  
 2             | Marley          | second article |    3        |         2           | waiting for more   

我想要的是什么:

articles.id   | articles.writer | articles.text  | comments.id | comments.article_id | comments.comment
 1            | Bob             | first article  |    1        |         1           | i love this article
NULL          | NULL            |    NULL        |    2        |         1           | good one  
 2            | Marley          | second article |    3        |         2           | waiting for more 

那么如何选择每篇文章及其评论,并且只显示一篇文章而不是每篇评论

谢谢

1 个答案:

答案 0 :(得分:6)

您可以在MySQL中使用用户变量来执行此操作:

SELECT 
  case when rownum =1 then id else null end id,
  case when rownum =1 then writer else null end writer,
  case when rownum =1 then text else null end text,
  comment
FROM
(
  SELECT a.id, a.writer, a.text,
    c.article_id, c.comment, 
    @rownum := case
                when @prev = a.id
                  and @prev_art = c.article_id
                then @rownum+1 else 1 end rownum,
    @prev := a.id p_id,
    @prev_art := c.article_id p_art
  FROM articles a
  LEFT JOIN comments c
    ON a.id = c.article_id 
  ORDER BY a.id, article_id
) src

请参阅SQL Fiddle with Demo

结果是:

|     ID | WRITER |           TEXT |             COMMENT |
----------------------------------------------------------
|      1 |    Bob |  first article | i love this article |
| (null) | (null) |         (null) |            good one |
|      2 | Marley | second article |    waiting for more |

编辑,如果您需要comment.id,则可以将其添加到结果中:

SELECT 
  case when rownum =1 then id else null end id,
  case when rownum =1 then writer else null end writer,
  case when rownum =1 then text else null end text,
  commentid,
  article_id,
  comment
FROM
(
  SELECT a.id, a.writer, a.text,
    c.article_id, c.comment, c.id commentid,
    @rownum := case
                when @prev = a.id
                  and @prev_art = c.article_id
                then @rownum+1 else 1 end rownum,
    @prev := a.id p_id,
    @prev_art := c.article_id p_art
  FROM articles a
  LEFT JOIN comments c
    ON a.id = c.article_id 
  ORDER BY a.id, article_id
) src

SQL Fiddle with Demo。结果是:

|     ID | WRITER |           TEXT | COMMENTID | ARTICLE_ID |             COMMENT |
-----------------------------------------------------------------------------------
|      1 |    Bob |  first article |         1 |          1 | i love this article |
| (null) | (null) |         (null) |         2 |          1 |            good one |
|      2 | Marley | second article |         3 |          2 |    waiting for more |