MySQL:正确舍入百分比

问题描述

我在 MysqL 数据库中有一个t(int,float,float),其值如下:

id v1 v2 v3
1 0.25 0.75 0
2 0.125 0 0.875

保证每行 v1+v2+v3==1。

注意:v1、v2 和 v3 是浮点数,因此在某些情况下 v1+v2+v3 可能是 1 +/- 1E-38

我需要在输出生成整数百分比(即 0 到 100 之间的整数),这将为每条记录加起来为 100,同时尽可能接近地表示源值。

对于上述数据样本,预期输出为:

id p1 p2 p3
1 25 75 0
2 13 0 87

或者:

id p1 p2 p3
1 25 75 0
2 12 0 88

(以上两个输出都是可以接受的)

我目前的解决方案:

第一步:计算p1tmp = round(100*v1),p2tmp = round(100*v2),p3tmp = round(100*v3)

第 2 步:计算:

p1 = CASE
    WHEN p1tmp = GREATEST(p1tmp,p2tmp,p3tmp) AND GREATEST(p1tmp,p3tmp) > LEAST(p1tmp,p3tmp)
    THEN 100 - p2tmp - p3tmp ELSE p1tmp END AS p1,p2 = CASE
    WHEN p2tmp = GREATEST(p1tmp,p3tmp)
    THEN 100 - p1tmp - p3tmp ELSE p2tmp END AS p2,p3 = CASE
    WHEN p3tmp = GREATEST(p1tmp,p3tmp)
    THEN 100 - p1tmp - p2tmp ELSE p3tmp END AS p3

虽然在数学上是正确的,但上述解决方案并不是很优雅。代码复杂、不可读且不易扩展到具有 4 个或 5 个值的情况(我目前的要求实际上是 4 个值,即 v1、v2、v3、v4,但将来可能会改变)。

我尝试应用舍入到最接近偶数的方法,但它只适用于一对变量(即 v1、v2,而不是 v1、v2、v3)。

欢迎提出任何想法。

解决方法

MSSQL 解决方案,但可以轻松采用。 -- 做一个支点

declare @id int
set @id =4 -- take a single row data

create table #row(x float,procent int,col int);
insert into #row
 select v1,1  from t where id = @id union all
 select v2,2  from t where id = @id union all 
 select v3,3  from t where id = @id;


with cte as 
(select x,case when x != (select max(x) from #row) then ROUND(x*100,0) else ROUND(x*100,1) end x2
from #row )

select * from cte -- unpivoto

drop table #row

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...