MySQL - JOIN的table1列,其中AVG为table2和table3中的两列

时间:2017-11-06 23:53:40

标签: mysql join average

我正在尝试组合以下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链接到comments.page_id和ratings.page_id

更具体地说,我想获得评论的平均值。评分和评分。评分AS' star_total'并将这个新列与来自" pages"的相应行组合在一起,这样我得到一个这样的表结构:id,identifier,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`
)

2 个答案:

答案 0 :(得分:0)

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

  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

答案 1 :(得分:0)

我们可以这样做:

    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