使用Join并使用SUM显示市场排名。不工作

时间:2015-04-24 15:26:15

标签: mysql

我有这个mySQL查询:

SELECT market.*, market_chain.* FROM market
        JOIN market_chain
        ON market.mc_id = market_chain.mc_id

这很好用。 “market”表还包含名为“market_id”的字段。 我有另一个名为“market_ranking”的表,它与market_id的“市场”表有关系。 我想要的是显示我之前查询的每个结果+其市场排名平均值。

考虑到有时market_review不包含特定market_id的排名 market_review.mr_rank是市场的排名。 (只是1到5之间的数字) 我试过了:

 SELECT market.*, market_chain.*, SUM(market_review.mr_rank) FROM market
            JOIN market_chain
            ON market.mc_id = market_chain.mc_id
            INNER JOIN market_review
            ON market_review.market_id = market.market_id

这导致视图不正确,一切都搞砸了。我也没有真正得到平均排名。

我希望我的问题足够明确。

2 个答案:

答案 0 :(得分:0)

试试这个:

SELECT market.*, market_chain.*, SUM(market_review.mr_rank), AVG(market_review.mr_rank) FROM market
LEFT JOIN market_chain
ON market.mc_id = market_chain.mc_id
LEFT JOIN market_review
ON market_review.market_id = market.market_id
GROUP BY market.market_id

如果它没有帮助,请提供一些数据或sqlfiddle是完美的。

答案 1 :(得分:0)

问题并不完全清楚,但听起来market_review中可能有多行具有相同的market_id值。也就是说,它是marketmarket_review之间的一对多关系。

获得平均排名的一种方法"来自market_review的是使用内嵌视图来计算每个market_id的平均值。我们更有意义的是我们想要使用AVG聚合函数,而不是SUM聚合。

我们可以将内联视图的结果加入到原始查询中。由于原始查询返回的每个market_review market_id中都没有行可能听起来有可能,因此我们希望将其作为"外部& #34;加入。

这样的事情:

 SELECT m.*
      , c.*
      , a.avg_mr_rank
   FROM market m
   JOIN market_chain c
     ON c.mc_id = m.mc_id
   LEFT
   JOIN ( SELECT r.market_id
               , AVG(r.mr_rank) AS avg_mr_rank
            FROM market_review r
           GROUP BY r.market_id
        ) a
     ON a.market_id = m.market_id
  ORDER BY m.market_id

如果你想要mr_rank的SUM而不是AVG,只需用SUM替换AVG。

还有其他几种查询模式会返回相同的结果。例如,我们可以进行"外连接"到market_review,然后在整个结果集上使用GROUP BY market_id。也可以在SELECT列表中使用相关子查询。这些陈述中的每一个都将表现出不同的性能特征。

但上面的查询最接近"保留原始查询"和"添加平均排名"。

在SELECT列表中包含相关子查询的查询通常也不会执行。

 SELECT m.*
      , c.*
      , ( SELECT AVG(r.mr_rank)
            FROM market_review r
           WHERE r.market_id = m.market_id
        ) AS avg_mr_rank
   FROM market m
   JOIN market_chain c
     ON c.mc_id = m.mc_id
  ORDER BY m.market_id

我建议的另一个选择是做"外连接"并使用GROUP BY来折叠行;但是这种方法使用GROUP BY的非标准MySQL扩展,这将在其他数据库中引发错误,并且是未经证实的人的混乱和惊愕的来源。

我不建议这样做,但这也会返回指定的结果,假设market_id是主键或在market中是唯一的,并且假设MySQL sql_mode没有&#39 ; t包括ONLY_FULL_GROUP_BY)

 SELECT m.*
      , c.*
      , AVG(r.mr_rank) AS avg_mr_rank
   FROM market m
   JOIN market_chain c
     ON c.mc_id = m.mc_id
   LEFT
   JOIN market_review r
     ON r.market_id = m.market_id
  GROUP BY m.market_id
  ORDER BY m.market_id