SQL 未达到 100% 的百分比
SQL percentage not reaching 100%
你好抱歉英语不好或什么的。
我的 SQL 查询有点问题,如果我有 table 这样的
item amount itemtype sumamount percentage
1 100 1 300 0,33
2 100 2 300 0,33
3 100 3 300 0,33
with s as (
select itemtype, sum(amount) as sum
from test3
group by itemtype)
x as (
select s.*, amount/sum as persen from test3 t inner join s on t.itemtype = s.itemtype)
select sum(persen) from x
我正在寻找最终未达到 100% 的百分比之和,如何解决此问题?谢谢
因为您要除以 2 个数字,所以它们可能不会四舍五入到准确的数字。
例如 1/3 是 0.33333333... 直到时间结束,但这不能存储在计算机系统中,因此我们需要在某个地方将它们向下舍入。
您可以通过将总和转换为不同的数字类型(例如实数)来提高计算精度。
with s as (
select itemtype, sum(amount) as sum
from test3
group by itemtype)
x as (
select s.*, CAST(amount as real)/sum as persen from test3 t inner join s on t.itemtype = s.itemtype)
select sum(persen) from x
如果我们从这里开始:
with s as ( select itemtype, sum(amount) as sum_c
from test3
group by itemtype),
x as ( select s.*, amount/sum_c as persen
from test3 t
inner join s on t.itemtype = s.itemtype)
select sum(persen) from x;
请不要使用关键字作为别名(例如:sum)
这个 returns 你的例子中的第 3 个,你的问题是:"SQL percentage not reaching 100%"。所以不太清楚你想在这里完成什么...
您的第一个查询将返回:
itemtype sum_c
1 100
2 100
3 100
当您按项目类型分组时,这是合乎逻辑的。
在您的第二个查询中,您将 sum_c
的结果除以 100/100 的金额,结果是:
itemtype sum_c persen
1 100 1
2 100 1
3 100 1
因此,请使用您希望从此示例数据获得的结果更新您的问题。
这是您的示例的演示:https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=fd6244948053822b1f339d7939ef7723
也许它会帮助你或其他人给你一个解决方案...
简单的解决办法就是多保留小数点,不用担心差异。您的查询似乎更简单地写为:
select t3.*,
amount * 1.0 / sum(amount) over (partition by itemtype) as ratio
from test3 t3;
这应该 return 结果类似于 0.3333333。如果您真的希望一个值稍微偏离以使总和为 100%。然后你可以做一些操作和算术:
select t3.*,
(case when row_number() over (partition by itemtype order by item) = 1
then (sum(ratio) over (partition by itemtype order by item) - ratio)
else ratio
end) as ratio
from (select t3.*,
convert(decimal(10, 4), amount * 1.0 / sum(amount) over (partition by itemtype)) as ratio
from test3 t3
) t3;
额外的算法确保值加起来为 1。
你好抱歉英语不好或什么的。
我的 SQL 查询有点问题,如果我有 table 这样的
item amount itemtype sumamount percentage
1 100 1 300 0,33
2 100 2 300 0,33
3 100 3 300 0,33
with s as (
select itemtype, sum(amount) as sum
from test3
group by itemtype)
x as (
select s.*, amount/sum as persen from test3 t inner join s on t.itemtype = s.itemtype)
select sum(persen) from x
我正在寻找最终未达到 100% 的百分比之和,如何解决此问题?谢谢
因为您要除以 2 个数字,所以它们可能不会四舍五入到准确的数字。 例如 1/3 是 0.33333333... 直到时间结束,但这不能存储在计算机系统中,因此我们需要在某个地方将它们向下舍入。 您可以通过将总和转换为不同的数字类型(例如实数)来提高计算精度。
with s as (
select itemtype, sum(amount) as sum
from test3
group by itemtype)
x as (
select s.*, CAST(amount as real)/sum as persen from test3 t inner join s on t.itemtype = s.itemtype)
select sum(persen) from x
如果我们从这里开始:
with s as ( select itemtype, sum(amount) as sum_c
from test3
group by itemtype),
x as ( select s.*, amount/sum_c as persen
from test3 t
inner join s on t.itemtype = s.itemtype)
select sum(persen) from x;
请不要使用关键字作为别名(例如:sum)
这个 returns 你的例子中的第 3 个,你的问题是:"SQL percentage not reaching 100%"。所以不太清楚你想在这里完成什么...
您的第一个查询将返回:
itemtype sum_c 1 100 2 100 3 100
当您按项目类型分组时,这是合乎逻辑的。
在您的第二个查询中,您将 sum_c
的结果除以 100/100 的金额,结果是:
itemtype sum_c persen 1 100 1 2 100 1 3 100 1
因此,请使用您希望从此示例数据获得的结果更新您的问题。
这是您的示例的演示:https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=fd6244948053822b1f339d7939ef7723 也许它会帮助你或其他人给你一个解决方案...
简单的解决办法就是多保留小数点,不用担心差异。您的查询似乎更简单地写为:
select t3.*,
amount * 1.0 / sum(amount) over (partition by itemtype) as ratio
from test3 t3;
这应该 return 结果类似于 0.3333333。如果您真的希望一个值稍微偏离以使总和为 100%。然后你可以做一些操作和算术:
select t3.*,
(case when row_number() over (partition by itemtype order by item) = 1
then (sum(ratio) over (partition by itemtype order by item) - ratio)
else ratio
end) as ratio
from (select t3.*,
convert(decimal(10, 4), amount * 1.0 / sum(amount) over (partition by itemtype)) as ratio
from test3 t3
) t3;
额外的算法确保值加起来为 1。