【问题标题】:MYSQL JOIN all child rows and display parent row once onlyMYSQL JOIN 所有子行并仅显示一次父行
【发布时间】:2013-01-25 21:05:54
【问题描述】:

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

文章表:

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

我想选择每篇文章及其下方的 cmets。我使用以下查询:

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 

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

谢谢

【问题讨论】:

  • 在加入时,您正在组合结果。如果您不想重复,我认为您需要 2 个查询。
  • 我认为应该有其他方法...在 php while 循环中查询也会停止第一个查询,所以我认为这也行不通...谢谢 :)

标签: php mysql sql database join


【解决方案1】:

您可以在 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 |

【讨论】:

  • 现在第二条评论的ID不见了,根据你的结果显示为null...
  • @Sam 这在其他具有窗口功能的数据库中要容易得多。然后,您可以根据数据的分区应用行号。
  • @MichaelSamuel 我不明白,您需要更多列还是这是正确的结果?如果需要,您可以将comment.id 添加到结果中——参见这个演示——sqlfiddle.com/#!2/c5639/15
  • 不,这不是正确的结果,因为现在缺少评论 ID...我希望只输出一次文章信息,然后输出文章的 cmets...现在 cmets id 列是从结果中得出结论......也没有一种简单的方法可以实现这一目标吗?谢谢:)
  • @MichaelSamuel 您所要做的就是将列添加到查询中。查看我的编辑
猜你喜欢
  • 2011-08-28
  • 1970-01-01
  • 1970-01-01
  • 2018-07-27
  • 2013-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-22
相关资源
最近更新 更多