【问题标题】:How to calculate sum of group in SQL?如何在 SQL 中计算组的总和?
【发布时间】:2020-07-22 04:00:02
【问题描述】:

我正在尝试查找如何计算适用于涉及“NA”值的公式的新 SQL 列。我认为由于“NA”值或由于我的分组,我没有得到我想要的结果。请看下表和公式:

我的表如下:

website session score
 google    1       1
 google    2       NA
 bbc       3       2
 bbc       4       4
 bbc       5       5

我用来创建新计算字段的公式如下:

select
    website,
    (sum(score IN (4,5))/sum((score is not null)) - sum(score IN (1,2))/sum(score is not null))*100 as new_column
from 
    my_table
group by 
    website

本质上该公式正在尝试执行以下操作:

将分数列中 4 或 5 的值相加,然后将它们除以分数列中确实存在的数字的总和。

然后扣除以下内容:

将分数列中 1 或 2 的值相加,然后将它们除以分数列中确实存在的数字的总和。

最后:

将整个输出乘以 100

公式必须应用于每个组。

所以你应该有以下期望的结果:

只取第一组“google”

您有 4 个非空值。您有 2 个值,其中值为 IN (1,2),0 值为 (4,5)。

所以你会得到以下公式:

((0/4)-(2/4))*100

-2/4 * 100

= -50

但是,在 SQL 中计算时,我收到的值是 -100。这对我来说没有意义。谁能帮忙?

【问题讨论】:

  • 您可以“选择”每个操作来检查错误在哪里,但我敢打赌,问题是您按网站分组,而 google 只有 2 行,而不是 4 行,其中之一所选行为空,因此不计算在内...
  • 这个查询对我来说很好。顺便说一句:我想这是 MySQL 还是 MariaDB?然后请添加该标签。 SQL 问题应始终使用您正在使用的 DBMS 进行标记。
  • SQLITE 并添加了标签
  • @AntonioVenerosoContreras 我如何计算空行?
  • @BeansOnToast 在您的示例中,您声明有 2 个值,其中“google”的值为 IN(1,2)。但是,在您的表上,只有 1 条记录的分值为 IN(1,2)。对于 google,第二条记录是 NA 或 null。

标签: sql sqlite


【解决方案1】:

Google 有一个非空值。它的总和是一。所以你的公式得到 (0-1/1)*100 即 -100,这就是它给出的结果。

我认为您想要的是所有 Google 记录的计数除以所有非空记录的计数?

【讨论】:

  • 那么公式是否正确?我的意思是,如果它给出 -100,那将是正确的!
  • 是的,按照我的理解,公式按照您的描述进行。您的手动示例做了其他事情。
  • 啊,好吧 - 第二组 BBC 的预期结果是什么?
  • (2/3 - 1/3) * 100 = 100/3 = 33.333
  • 是的 - 得到相同的答案,所以公式是正确的!感谢您的帮助!
【解决方案2】:

我建议将每个总和乘以 1.0,这样它就不会将总和四舍五入为 int 值,这会导致 'bbc' 组为零 (0)。

这是您查询的更新版本(另请查看 SQL fiddle http://sqlfiddle.com/#!5/5fca1/8):

select website,
    (sum(score IN (4,5)) * 1.0/sum(score is not null) - sum(score IN (1,2)) * 1.0/sum(score is not null))*100.0 as new_column
from my_table
group by website

【讨论】:

  • 虽然这不能回答问题,但这仍然是个好建议。我发现在某些 SQL 方言(包括 SQLite)中,/ 的意思不是“除法”,而是“取决于类型的除法或整数除法”,这很可怕。我无法想象有多少程序错误可能源于这个“功能”:-(
【解决方案3】:

我认为您正在寻找每个组的 (4,5) 和 (1,2) 百分比之间的差异。由于在聚合中忽略空值,您可以简单地做

(avg(score in (4,5)) - avg(score in (1,2)))*100

【讨论】:

    【解决方案4】:

    从您的手动示例中,您可以先对所有非空值求和,然后在代码中使用该值 -

    WITH NN_SUM AS (SELECT SUM(score is not null) NOT_NULL_SUM
                    FROM my_table)
    SELECT website,
           (((sum(score IN (4,5)) - sum(score IN (1,2))) / NOT_NULL_SUM) * 100 as new_column
    FROM my_table
    CROSS JOIN NN_SUM
    GROUP BY website;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多