我有这个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
这导致视图不正确,一切都搞砸了。我也没有真正得到平均排名。
我希望我的问题足够明确。
答案 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
值。也就是说,它是market
和market_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