如何设置新列等于子查询PostGreSQL

时间:2017-04-06 02:07:30

标签: postgresql

完全披露:我已经看到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;

1 个答案:

答案 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.?;