MySQL-基于多个列不起作用的百分比增加

时间:2019-03-16 23:09:28

标签: mysql sql percentage

我正在尝试编写一个查询,该查询基于三列A1,A2,A3计算百分比增加。目的是确定增加/减少的百分比。请查看简化的Excel计算

enter image description here

这里A1,A2,A3是我的表PCLS中的三列,通过它们我将更新表PCNT。计算很简单,我首先计算PCNT的次数。A出现在A1,A2,A3列中(在这种情况下为4,52,3),然后应用10000的因子来获取列中的初始值S10K。 CV列从另一个来源获取当前值,现在我的目标是确定CV与S10K的百分比增加或减少。在Excel示例中,它将是(630135.6-590000)/(590000)* 100,对应于6.80%的增长。在Excel中似乎很简单,但在MySQL中却无法正确计算。我尝试了以下

UPDATE PCNT SET `R%`= (
    (
        (
            (
                (SELECT SUM(`CV`) from PCLS WHERE `A1`=PCNT.`A`) 
                + (SELECT SUM(`CV`) from PCLS WHERE `A2`=PCNT.`A`) 
                + (SELECT SUM(`CV`) from PCLS WHERE `A3`=PCNT.`A`)
            ) 
            - (
                (
                    (SELECT count(`CV`) from PCLS WHERE `A1`=PCNT.`A`)
                    + (SELECT count(`CV`) from PCLS WHERE `A2`=PCNT.`A`)
                    + (SELECT count(`CV`) from PCLS WHERE `A3`=PCNT.`A`)
                )*10000
            )
        )
    ) 
    / 
    (
        (
            (SELECT count(`CV`) from PCLS WHERE `A1`=PCNT.`A`)
            + (SELECT count(`CV`) from PCLS WHERE `A2`=PCNT.`A`)
            + (SELECT count(`CV`) from PCLS WHERE `A3`=PCNT.`A`)
        ) * 10000
    )
)*100;

但是,这似乎仅在PCNT。A存在于所有三个列A1,A2,A3中时才有效。如果在任一列中都不存在它,则结果为NULL。

我尝试了以下替代方法,但问题并没有消失

UPDATE PCNT
set `R%` = ((((((SELECT SUM(`CV`) from PCLS WHERE `A1`=PCNT.`A`) - ((SELECT 
count(`CV`) from PCLS WHERE `A1`=PCNT.`A`)*10000))/((SELECT count(`CV`) from 
PCLS WHERE `A1`=PCNT.`A`)*10000))*100))) + ((((((SELECT SUM(`CV`) from PCLS 
WHERE `A2`=PCNT.`A`) - ((SELECT count(`CV`) from PCLS WHERE 
`A2`=PCNT.`A`)*10000))/((SELECT count(`CV`) from PCLS WHERE 
`A2`=PCNT.`A`)*10000))*100))) + ((((((SELECT SUM(`CV`) from PCLS WHERE 
`A3`=PCNT.`A`) - ((SELECT count(`CV`) from PCLS WHERE 
`A3`=PCNT.`A`)*10000))/((SELECT count(`CV`) from PCLS WHERE 
`A3`=PCNT.`A`)*10000))*100)));

如果我使用以下查询,将搜索范围限制为仅A1列,那么一切似乎都可以正常运行。该查询的评估结果类似于在Excel屏幕截图中所看到的16.34%。

UPDATE PCNT
set `R%` = (((SELECT SUM(`CV`) from PCLS WHERE `A1`=PCNT.`A`) - ((SELECT 
count(`CV`) from PCLS WHERE `A1`=PCNT.`A`)*10000))/((SELECT count(`CV`) from 
PCLS WHERE `A1`=PCNT.`A`)*10000))*100;

此刻,我将A2中不存在的任何PCNT值包括在A2和A3中。{2}计算为NULL。我只需要查询返回(630135.6-590000)/(590000)* 100 = 6.80%,但是我很难使它正常工作。我觉得加法运算会引起问题。

是否有正确的方法或替代方法。我尝试进行多项更改,但未成功。

A

以上两个查询,如果独立运行似乎可以正常工作,则当我使用加法运算符时问题就开始了。

1 个答案:

答案 0 :(得分:1)

  

此刻,我将A2和A3包括在A1中不存在的任何PCNT.A值,A2的结果为NULL。我觉得加法运算会引起问题。

其中一个成员为NULL的加法返回NULL(其他算术运算也是如此)。您将需要用COALESCE()包裹子查询,以返回0

最重要的是,我确实怀疑您的查询可能会被重写,以对聚合子查询上的LEFT JOIN替换多个内联查询,例如:

UPDATE pcnt pn
LEFT JOIN (SELECT a1, SUM(cv) sumcv, COUNT(cv) cntcv FROM pcls GROUP BY a1) pa1 ON pa1.a1 = pn.a
LEFT JOIN (SELECT a2, SUM(cv) sumcv, COUNT(cv) cntcv FROM pcls GROUP BY a2) pa2 ON pa2.a2 = pn.a
LEFT JOIN (SELECT a3, SUM(cv) sumcv, COUNT(cv) cntcv FROM pcls GROUP BY a3) pa3 ON pa3.a3 = pn.a
SET pn.`R%` = 
    ( 
        COALESCE(pa1.sumcv, 0) + COALESCE(pa2.sumcv, 0) + COALESCE(pa3.sumcv, 0)
        - (COALESCE(pa1.cntcv, 0) + COALESCE(pa2.cntcv, 0) + COALESCE(pa3.cntcv, 0)) * 10000
    ) 
    / ((COALESCE(pa1.cntcv, 0) + COALESCE(pa2.cntcv, 0) + COALESCE(pa3.cntcv, 0)) * 10000)
    * 100