【问题标题】:MySQL left join query - getting data from three tablesMySQL左连接查询 - 从三个表中获取数据
【发布时间】:2014-01-23 19:44:42
【问题描述】:

我在数据库中有以下表格:

post:

+---------------+----------------+------+-----+---------+----------------+
| Field         | Type           | Null | Key | Default | Extra          |
+---------------+----------------+------+-----+---------+----------------+
| post_id       | int(11)        | NO   | PRI | NULL    | auto_increment |
| post_content  | varchar(50000) | NO   |     | NULL    |                |
| post_date     | datetime       | NO   |     | NULL    |                |
| post_summary  | varchar(1000)  | YES  |     | NULL    |                |
| post_title    | varchar(300)   | NO   |     | NULL    |                |
| post_visitors | int(11)        | NO   |     | NULL    |                |
| user_id       | int(11)        | NO   | MUL | NULL    |                |
| category_id   | int(11)        | NO   | MUL | NULL    |                |
+---------------+----------------+------+-----+---------+----------------+

user

+---------------+--------------+------+-----+---------+----------------+
| Field         | Type         | Null | Key | Default | Extra          |
+---------------+--------------+------+-----+---------+----------------+
| user_id       | int(11)      | NO   | PRI | NULL    | auto_increment |
| user_image    | varchar(500) | YES  |     | NULL    |                |
| user_name     | varchar(45)  | NO   |     | NULL    |                |
| user_password | varchar(45)  | NO   |     | NULL    |                |
| user_type     | varchar(30)  | NO   |     | NULL    |                |
| user_username | varchar(45)  | NO   |     | NULL    |                |
+---------------+--------------+------+-----+---------+----------------+

comment

+-----------------+--------------+------+-----+---------+----------------+
| Field           | Type         | Null | Key | Default | Extra          |
+-----------------+--------------+------+-----+---------+----------------+
| comment_id      | int(11)      | NO   | PRI | NULL    | auto_increment |
| comment_content | varchar(600) | NO   |     | NULL    |                |
| comment_date    | datetime     | NO   |     | NULL    |                |
| comment_title   | varchar(300) | NO   |     | NULL    |                |
| user_id         | int(11)      | NO   | MUL | NULL    |                |
| post_id         | int(11)      | NO   | MUL | NULL    |                |
+-----------------+--------------+------+-----+---------+----------------+

我需要一个返回 post_titlepost_summarypost_datenumber_of_comments_for_this_postuser_name 的查询,按 number_of_comments_for_this_post 排序(降序)。

基本上我需要来自所有三个表的数据。我知道如何离开两个表并获取一些数据。例如:

SELECT p.post_title, p.post_summary, p.post_date, u.user_name 
FROM post p LEFT JOIN user u ON p.user_id=u.user_id;

如何通过加入第三个表(评论)来扩展此查询并添加一个字段 - 'number of posts cmets' 按评论最多的帖子排序(desc)?

【问题讨论】:

    标签: mysql left-join


    【解决方案1】:

    Join 只是一个 relational algebra 运算符。关系代数只是另一种查询形式。表是一个关系,对它们的操作会产生其他关系。您可以使用多个操作来生成结果关系。 MySQL JOIN 手册页也建议这样做。

    要计算一组行的一些统计数据,您需要aggregate functions。在这种情况下,您需要COUNT

    SELECT
        post_title,
        post_summary,
        post_date,
        COUNT(comment_id) AS comment_cnt,
        user.user_name
    FROM
        post
        LEFT JOIN user USING(user_id)
        LEFT JOIN comment USING(post_id)
    GROUP BY
        post_id
    ORDER BY
        comment_cnt DESC
    

    【讨论】:

      【解决方案2】:

      类似的东西

       SELECT 
        p.post_id,
        p.post_date,
        p.post_summary,
        p.post_title,
        u.user_name,
        COUNT(c.comment_id) AS number_of_post_comments 
      FROM
        post p 
        LEFT JOIN COMMENT c 
          ON p.post_id = c.post_id 
        LEFT JOIN USER u 
          ON p.user_id = u.user_id
      GROUP BY p.post_id  
      ORDER BY number_of_post_comments  DESC
      

      【讨论】:

      • 这个查询没有返回有效结果
      • 我已经把post的表格内容、查询和结果放到了文本文件中,你可以在这里看到:ge.tt/71ld1cC1/v/0?c
      • 感谢报告..我更正了我的答案,我希望现在即使我无法测试它也能正常工作。
      • @Wlad 您可能错过了mysqldump 实用程序。它以 SQL 查询的形式转储表内容。转储易于导入和试验。但是sqlfiddle 还是更好。
      • @StarsSky 是的,现在可以了,只需在末尾添加desc。谢谢
      【解决方案3】:

      简单,继续正常语法

      select p.post_title, p.post_summary, p.post_date, u.user_name 
      from post p 
      left join user u 
      on p.user_id = u.user_id
      left join comment c
      on p.post_id = c.post_id
      

      除了一个有用的小帮手:

      如果您遇到要连接的两个表中的列具有相同名称的情况,请使用 USING() 让你的mysql绝地生活更轻松!

      select p.post_title, p.post_summary, p.post_date, u.user_name 
      from post p 
      left join user u 
      USING(user_id)
      left join comment c
      USING(post_id)
      

      【讨论】:

      • 学徒,不要使用 USING()。在较大的查询中,它变得太混乱了。而且没有性能优势。
      • 当然这对性能没有好处,但也不是缺点。而且它的代码更少,我通过阅读诸如用户 u 然后 u.x = c.y 之类的表词缀而感到头疼,我认为这根本不会令人困惑,但这是一个品味问题!无论如何,大型查询很难阅读,它的 USING() 或 ON 语句无关紧要。用新行格式化您的查询完成了使其可读性的一半工作......
      • @Steini 您没有在结果中包含 number_of_posts cmets 字段,并按该字段排序
      • 当然。每个人都有他自己的,但 USING() 绝对是黑暗的一面。
      • @Wlad,是的,我错过了......但是现在很多人在我之前发布了这个,所以他们应该获得他们应得的代表,我现在真的不需要再调整了。
      猜你喜欢
      • 2023-03-07
      • 2012-05-02
      • 2013-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多