【问题标题】:Retrieving both a 'count where' and and overall count simultaneously同时检索“计数位置”和总体计数
【发布时间】:2013-03-11 19:43:38
【问题描述】:

我有一个餐厅评分和评论数据库,每家餐厅可能有 1 到 1000 条评论。

我首先尝试找出哪些餐厅的评论中包含“taco”一词的评分最多为 4+,然后我使用以下代码对其进行了处理:

    select id, count(id) from test where (comment like '%taco%') AND rating >= 3 group by id order by count(id) DESC;

因此,例如,如果餐厅 X 有 30 4 条以上的评分评论,其中包含“taco”,我会为该行获得“X|30”。

我想添加两个附加功能:

  1. 列出每家餐厅的评论总数(无条件)
  2. 对餐厅的所有评论(包括“taco”)给出平均评分。

如果餐厅 X 总共有 150 条评论,其中 30 条评分为 4+ 并且包括“taco”,而这 30 条评论的平均评分为 2.5,我会得到:

'X|30|150|2.5|'

我如何得到这个结果?

【问题讨论】:

  • 4+ 评分的评论的平均值怎么可能是 2.5?
  • 不应该有 4+ 个评分是 ratings >= 4
  • 很好,呸。我的意思是包含“taco”在内的所有餐厅评论的平均评分是 2.5。所以有 30 条 4+ 评分的评论和很多较低的评论。

标签: sql sqlite


【解决方案1】:

这样的事情可能会奏效。

select id
, count(*) totalreviews
, sum(case when rating >= 3 and comment like '%taco%' then 1 else 0 end) ratings4plus
, avg(case when rating >= 3 and comment like '%taco%' then rating else null end) avgratings4plus
from test
group by id

【讨论】:

    【解决方案2】:

    这是未经测试的,但您可以尝试类似的方法

    select id,
           count(id), 
           sum(case when (comment like '%taco%' and rating >=3) then 1 
                    else 0 end) taco_rating, 
           avg(case when comment like '%taco%' then rating else null end ) avg_taco
      from test
     group by id
    

    【讨论】:

      【解决方案3】:

      使用子查询:

      SELECT id,
             (SELECT COUNT(*)
              FROM test
              WHERE id = t1.id
                AND comment LIKE '%taco%'
                AND rating >= 3),
             (SELECT COUNT(*)
              FROM test
              WHERE id = t1.id),
             (SELECT AVG(rating)
              FROM test
              WHERE id = t1.id
                AND comment LIKE '%taco%'
                AND rating >= 3),
      FROM (SELECT DISTINCT id
            FROM test) AS t1
      

      【讨论】:

        【解决方案4】:

        对于4+,你的测试应该是rating > 3而不是rating >= 3,但是这样可以:

        select
            id,
            sum(case when comment like '%taco%'
                    AND rating > 3 then 1 else 0 end) as rating4plus_count,
            count(*) as all_ratings_count,
            avg(case when comment like '%taco%'
                    AND rating > 3 then rating else null end) as rating4plus_avg
        from test
        group by id
        order by 1 DESC;
        

        注意简写order by 1,这是按“列号 1”排序的 SQL 标准方式(而不是在 order by 子句中重复列 1 的表达式)

        【讨论】:

          猜你喜欢
          • 2023-03-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-05-09
          • 1970-01-01
          • 1970-01-01
          • 2018-09-02
          • 1970-01-01
          相关资源
          最近更新 更多