【问题标题】:MySQL - JOIN columns of table1 with AVG of two columns from table2 and table3MySQL - 将表 1 的列与表 2 和表 3 中的两列的平均值连接起来
【发布时间】:2017-11-06 23:53:40
【问题描述】:

我正在尝试合并以下 3 个表格的列。

pages:
*id* | *identifier*   | reference  | url        | ...
-------------------------------------------------------
 1   | 1              | page one   | http://... | ...
 2   | 3              | page two   | .....      | ...
 3   | 23             | page three | .....      | ...
 4   | 25             | page four  | .....      | ...
 5   | 43             | page five  | .....      | ...

comments:
page_id | *rating* | comment   | is_approved | name | ...
-------------------------------------------------------
 1      | 4        | bla bla   | 1           | joe  | ...
 2      | 5        | more bla  | 1           | jim  | ...
 2      | 3        | blub      | 1           | jill | ...
 3      | 1        | blubblub  | 1           | jack | ...
 4      | 2        | hey ho    | 0           | jimbo| ...
 5      | 4        | huhu      | 1           | mike | ...

ratings: 
page_id | *rating* | ip_address | ...
-----------------------------------
 1      | 3        | ...        | ...
 1      | 2        | ...        | ...
 2      | 5        | ...        | ...
 3      | 4        | ...        | ...
 4      | 0        | ...        | ...
 5      | 2        | ...        | ...

pages.id 链接到 cmets.page_id 和 ratings.page_id

更具体地说,我想获得 cmets.rating 和 rating.rating AS 'star_total' 的平均值,并将这个新列与“pages”中的相应行结合起来,这样我就得到了一个这样的表结构: id、标识符、star_total。

这是我一直在涉足的。我知道它不应该是这样的。这只是一个粗略的想法,据我所知:

SELECT pages.id, pages.identifier, star_total 
FROM pages LEFT JOIN 
(
    SELECT AVG(`rating`) FROM (
        SELECT 'rating' FROM comments
        WHERE `comments.is_approved = '1'
            AND comments.rating != '0'
            AND comments.page_id = ratings.page_id
        UNION ALL
        SELECT `rating`
        FROM ratings
        WHERE ratings.page_id = comments.page_id
    ) AS `star_total`
)

【问题讨论】:

  • 请以表格形式提供一些示例数据和所需的结果。不要将其作为 cmets 发布 - 请改用 Edit
  • 感谢您的两个回答!问题解决了。

标签: mysql join average


【解决方案1】:

我们可以这样做:

    SELECT pages.id
         , pages.identifier
         , q.star_total
      FROM pages
      LEFT
      JOIN ( SELECT t.page_id
                  , SUM(t.tot_rating)/SUM(t.cnt_rating) AS star_total
               FROM ( SELECT c.page_id           AS page_id
                           , SUM(c.rating)       AS tot_rating
                           , COUNT(c.rating)     AS cnt_rating
                        FROM comments c
                       WHERE c.is_approved = '1'
                         AND c.rating != '0'
                       GROUP BY c.page_id
                       UNION ALL
                      SELECT r.page_id        -- AS page_id
                           , SUM(r.rating)    -- AS tot_rating
                           , COUNT(r.rating)  -- AS cnt_rating
                        FROM ratings r
                       GROUP BY r.page_id
                    ) t
              GROUP BY t.page_id
           ) q
        ON q.page_id = pages.id

对于大型集合,那些内联视图(派生表)会很昂贵。获得等效结果的一种更简单的方法,可能会加剧内联视图的性能问题:

    SELECT pages.id
         , pages.identifier
         , q.star_total
      FROM pages
      LEFT
      JOIN ( SELECT t.page_id
                  , AVG(t.rating) AS star_total
               FROM ( SELECT c.page_id           AS page_id
                           , c.rating            AS rating
                        FROM comments c
                       WHERE c.is_approved = '1'
                         AND c.rating != '0'
                       UNION ALL
                      SELECT r.page_id        -- AS page_id
                           , r.rating         -- AS rating 
                        FROM ratings r
                    ) t
              GROUP BY t.page_id
           ) q
        ON q.page_id = pages.id

【讨论】:

    【解决方案2】:

    我认为您需要合并评分数据,然后计算每页的平均值,然后将该结果加入页面。

      SELECT
            p.id
          , p.identifier
          , u star_total
      FROM pages AS p
      LEFT JOIN (
                  SELECT
                        page_id
                      , AVG(rating) star_total
                  FROM (
                        SELECT
                              page_id
                            , rating
                        FROM comments
                        WHERE comments.is_approved = '1'
                        AND comments.rating != '0'
    
                        UNION ALL
    
                        SELECT
                              page_id
                            , rating
                        FROM ratings
                  ) d
                  GROUP BY
                        page_id
            ) AS u ON p.id = u.id
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-28
      • 1970-01-01
      • 2013-10-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多