[英]Get average rating for individual shop using mysql
I am joining two table ie shop table with rating table and want to fetch all shops list with individual shop rating, I have wriiten query for this but in output getting only those shops which have rating in rating table, but I want if shop don't have rating then show 0 else show as per table record.我正在加入两个表,即带有评级表的商店表,并希望获取具有单个商店评级的所有商店列表,我对此进行了书面查询,但在输出中仅获取那些在评级表中有评级的商店,但我想要如果商店不t 有评级然后显示 0 否则按表记录显示。
shop table:-商店表:-
id shop name
1 shop_1
2 shop_2
3 shop_3
4 shop_4
rating table评分表
id shop_id rating
1 1 3
2 4 2
Query:询问:
$this->db->select('shop.*,shop.id as shop_id');
$this->db->select('COALESCE(ROUND(AVG(rat.rating),1),0) as avgRate');
$this->db->from('shop');
$this->db->join('rating_reviews as rat', 'rat.shop=shop.id', 'left');
$this->db->get()->result_array();
current output:电流输出:
id shop_id avgRate
1 1 3
2 4 2
Expected output:预期输出:
id shop_id avgRate
1 1 3
2 2 0 //(no rating given for this shop)
3 3 0 //(no rating given for this shop)
4 4 2
The reason you're running into an error is that functions like AVG | COUNT
您遇到错误的原因是功能类似于AVG | COUNT
AVG | COUNT
are aggregate functions that is yo say that they aggregate all of the data and typically output a single record/result. AVG | COUNT
是聚合函数,也就是说它们聚合所有数据并通常输出单个记录/结果。
For example:例如:
shops
with id
as the Primary Key假设您有一个以id
为主键的桌子shops
The following queries will then return 1
row/result:以下查询将返回1
行/结果:
# Query # Output: # FIELD_1 # FIELD_2 (second statement)
SELECT COUNT(shop.id) FROM shop # 35
SELECT shop.id, COUNT(shop.id) FROM shop # 1 # 35
Both of the above statements would return 1
result.以上两个语句都将返回1
结果。 The first simply the count
for the number of shops ( 35
) and the second would additionally output the id
of the first shop ( 1
).第一个只是商店数量的count
( 35
),第二个将额外输出第一个商店的id
( 1
)。
Your query functions on the same princiiple, like COUNT
the AVG
function is an aggreagte function and will return 1
result/row from the query.您的查询功能基于相同的原则,例如COUNT
AVG
函数是一个聚合函数,将从查询中返回1
结果/行。
SELECT
shop.*, shop.id as shop_id,
COALESCE(ROUND(AVG(rat.rating),1),0) as avgRate
FROM shop
LEFT JOIN rating_reviews AS rat ON rat.shop=shop.id
-- Outputs: All fields from `shop` for the first shop followed by [shop_id] and [avgRate]
-- For example...
# shop.id # shop.name # shop.type # shop_id # avgRate
# 1 # Tesco # Supermarket # 1 # 3.5
There are however two ways to circumvent this behaviour:然而,有两种方法可以规避这种行为:
Using GROUP BY
使用GROUP BY
SELECT i, AVG(...) AS a FROM ... LEFT JOIN ... GROUP BY i
Nested SELECT
statements嵌套的SELECT
语句
SELECT i, (SELECT AVG(...) FROM ... WHERE ...) AS a FROM ...
SELECT
shop.*, shop.id as shop_id,
COALESCE(ROUND(AVG(rat.rating),1),0) as avgRate
FROM shop
LEFT JOIN rating_reviews AS rat ON rat.shop=shop.id
GROUP BY shop.id
SELECT
shop.*, shop.id as shop_id,
(SELECT
COALESCE(ROUND(AVG(rat.rating),1),0)
FROM rating_reviews as rat
WHERE rat.shop=shop.id
) as avgRate
FROM shop
I would like to suggest another approach, avoiding the join completely:我想建议另一种方法,完全避免加入:
select
distinct id,
(
select coalesce(round(avg(rat.rating), 1), 0)
from rating_reviews as rat where shop.id=rat.shop
) as avgRate
from shop
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.