如何将每行数据除以分组总和?及CREDITS表按日计算(TOTAL_LOAN*CREDITS_PERCENT)/SUM(TOTAL_LOAN)的SQL实现
嘿,我来帮你搞定这两个SQL问题!
问题1:如何将每行数据除以该行所在分组的总和?
要实现这个需求,窗口函数是最适合的工具——它能在保留每行原始数据的同时,计算出该行所属分组的聚合值(比如总和),完美解决“每行除以分组总和”的场景。
举个通用例子:假设你有一张表,包含category(分组列)和value(需要计算的数值列),要让每行的value除以该category的总和,可以这么写:
SELECT category, value, -- 用SUM() OVER (PARTITION BY 分组列)获取分组总和,再做除法 value / SUM(value) OVER (PARTITION BY category) AS value_divided_by_group_total FROM your_table;
这里的PARTITION BY category就是指定“按category列分组计算总和”,窗口函数会为每行匹配对应的分组总和,不会像普通GROUP BY那样把分组合并成单行。
问题2:CREDITS表的需求实现与SQL修正
先看你的需求:对每行计算(TOTAL_LOAN * CREDITS_PERCENT),再除以该行DAY_OPERATIONAL对应的TOTAL_LOAN总和。你的原代码有个核心问题:直接用SUM(total_loan)属于聚合函数,如果没有GROUP BY,它会把整个结果集合并成一行,没法保留每行的计算;如果加了GROUP BY day_operational,又会丢失每行的TOTAL_LOAN和CREDITS_PERCENT细节。
正确的SQL写法分两种情况:
情况1:只处理指定日期(比如'29.12.2021')的数据
SELECT day_operational, total_loan, credits_percent, -- 因为WHERE已经过滤了当天数据,OVER()就代表整个结果集的总和(也就是当天的TOTAL_LOAN总和) (total_loan * credits_percent) / SUM(total_loan) OVER () AS calculated_value FROM credits WHERE day_operational = '29.12.2021';
情况2:处理所有日期,每个日期单独计算总和
SELECT day_operational, total_loan, credits_percent, -- 用PARTITION BY day_operational,按日期分组计算各自的TOTAL_LOAN总和 (total_loan * credits_percent) / SUM(total_loan) OVER (PARTITION BY day_operational) AS calculated_value FROM credits;
关于GROUP BY的正确用法补充:
GROUP BY的作用是将行按指定列分组,然后对每个分组做聚合计算,结果集中每个分组只会显示一行。比如如果你只想统计每天的TOTAL_LOAN总和,就会这么用:
SELECT day_operational, SUM(total_loan) AS daily_total_loan FROM credits GROUP BY day_operational;
但你的需求是保留每行原始数据,同时引用分组的总和,这时候窗口函数(带OVER子句)才是正确选择,它不会改变结果集的行数,只是为每行附加对应的分组聚合值。
内容的提问来源于stack exchange,提问作者Miralisher Mirxomidov
相关产品推荐
相关产品推荐

