完全披露:我已经看到mySQL的这个问题有1个变体,而PostgreSQL的答案并不能让我满意。
我有2张桌子:评论&商家。在评论表中,针对此问题的唯一3个相关列是' business_id',' date' (yyyy-mm-dd)和星号(1-5),主键是(review_id)。在商家信息表格中,相关列是' business_id',' year'和' month'' '年'和'月'因为商家信息系统中还有另一列名为' review_count',它代表了每年每个月收到的商家评论数量。因此,此表的复合主键是(business_id,year,month)。
基本上,我正在尝试在商家信息表中创建一个列,其中每个月的每个月都会收到一个商家的平均评分(以星号表示)。
以下查询为我提供了我想要的确切结果:
SELECT round(CAST(AVG(stars) AS NUMERIC), 2)
FROM reviews_for_trending_businesses
WHERE business_id IN (SELECT DISTINCT(business_id)
FROM trending_businesses_v2)
GROUP BY business_id, EXTRACT("year" FROM reviews_for_trending_businesses.date), EXTRACT('month' FROM reviews_for_trending_businesses.date);
此代码返回列以及我要插入业务表的所有正确值。
但是,当我尝试实际更新表时,我收到一条错误,指出用作表达式的子查询返回了多行。这是我尝试更新的代码:
UPDATE trending_businesses_v2
SET avg_monthly_rating = (SELECT round(CAST(AVG(stars) AS NUMERIC), 2)
FROM reviews_for_trending_businesses
WHERE business_id IN (SELECT DISTINCT(business_id)
FROM trending_businesses_v2)
GROUP BY business_id, EXTRACT("year" FROM reviews_for_trending_businesses.date), EXTRACT('month' FROM reviews_for_trending_businesses.date);
我也尝试过其他一些解决方案,包括使用连接,但仍会遇到类似的错误。
更新:仍然没有答案,但越来越接近: 仍然无法弄清楚我在哪里出错了。我也不明白为什么我必须分组' rtb.date'在这里,如果我只从中提取值(如果我没有,则返回错误)。
UPDATE trending_businesses_v2 tb
SET avg_monthly_rating = t.val
FROM (SELECT business_id, EXTRACT("year" FROM rtb.date) AS year, EXTRACT('month' FROM rtb.date) AS month, round(CAST(AVG(stars) AS NUMERIC), 2) as val
FROM reviews_for_trending_businesses rtb
WHERE business_id IN (SELECT DISTINCT(business_id)
FROM trending_businesses_v2
)
GROUP BY business_id, year, month, rtb.date
) t
WHERE t.business_id = tb.business_id AND
t.year = tb.year AND t.month = tb.month;
答案 0 :(得分:0)
您需要匹配行,可能是使用业务ID和日期。像这样:
UPDATE trending_businesses_v2 tb
SET avg_monthly_rating = t.val
FROM (SELECT business_id, date_trunc('month', rtb.date) as yyyymm, round(CAST(AVG(stars) AS NUMERIC), 2) as val
FROM reviews_for_trending_businesses rtb
WHERE business_id IN (SELECT DISTINCT(business_id)
FROM trending_businesses_v2
)
GROUP BY business_id, date_trunc('month', rtb.date)
) t
WHERE t.business_id = tb.business_id AND
t.yyyymm = tb.?;