如何获得列的剩余百分比?

时间:2015-03-31 20:42:27

标签: sql sql-server database

我有一个格式如下的表,我们称之为“付款”

P_ID | P_PayNum | P_AmtPerc | P_Type
1    |    1     |   100     | FP1
2    |    1     |   50      | 2P1
3    |    2     |   50      | 2P1
4    |    1     |   25      | 4P1
5    |    2     |   0       | 4P1
6    |    3     |   0       | 4P1
7    |    4     |   0       | 4P1

我正在使用的表格中的问题,我正在努力想出最好的方法使用@TempTables创建一个UPDATE脚本并插入来查找AmtPerc = 0的所有值弄清楚如何取当前的非0(在这种情况下为4P1类型为25),并计算3中剩余的0(这将是25; 25 * 4 = 100)。

此表中有几个条目包含季度,半季度,半年度,双月度等的付款计划。同样少数几个也会遇到只出现第一部分百分比的问题(第一次支付)其余都是0.所以我试图找到动态查找所有0的最佳方法,找到代表该组的第一笔付款,并将其更新为正确的百分比,总计为100。 / p>

我真的不确定如何更好地说出这一点,并且希望有人理解我的意思。 如果有更好的方法来表达或解析这个问题,那么随意修改它以使其更有意义,并且发现的代码可以帮助其他人找出总计为100的剩余部分百分比。

3 个答案:

答案 0 :(得分:1)

我花了一点时间将我的面条包裹在这个面前,你有不同的付款代码(至少在这个例子中),但是当给定代码的所有付款时,百分比应该等于100%。

您想要的是找到未支付的款项,其中至少已经支付了一笔款项,并确定需要支付多少钱。

Select AccountNumber --I imagine this will be replaced by an account PK or item PK
  , 100 - sum(P_amtPerc) as RemainingPercent 
  , sum(case when P_amtPerc = 0 then 1 else 0 end) as RemainingPayments
From Payments
Group By AccountNumber --Once again this is a stand in for your real PK
having sum(P_amtPerc) < 100

这样做是因为我们使用群组声明来汇总表格的其余部分,在这种情况下,我们希望看到还有多少付款,以及剩余的百分比。我们使用having子句来过滤掉全额付款的帐户(例如:100%),因此我们确信我们只关注未付款或部分付款的帐户。希望这对你来说是正确的。

答案 1 :(得分:1)

这样的东西?

create table #temp (P_ID int, P_PayNum int, P_AmtPerc int, P_Type nvarchar(5));
insert into #temp values (1,1,100,'FP1');
insert into #temp values (2,1,50,'2P1');                    
insert into #temp values (3,2,50,'2P1');
insert into #temp values (4,1,25,'4P1');
insert into #temp values (5,2,0,'4P1');
insert into #temp values (6,3,0,'4P1');
insert into #temp values (7,4,0,'4P1');

select  A.P_ID
       ,A.P_PayNum
       ,A.P_AmtPerc
       ,A.P_Type
       ,case when T1.cntpct = 0 or A.P_AmtPerc > 0 then 0 else (100-T1.sumpct)/T1.cntpct end as Remainder
from #temp as A
join (select    P_Type
               ,sum(P_AmtPerc) as sumpct
               ,sum(case when P_AmtPerc = 0 then 1 else 0 end) as cntpct
from #temp
group by P_Type) as T1 on
T1.P_Type = A.P_Type;
drop table #temp;

答案 2 :(得分:1)

听起来你不仅要计算丢失的支付百分比,还要用它们更新基表。在SQL Server中,您可以这样做:

UPDATE p
SET p.P_AmtPerc = r.remaining_perc / r.num_zero
FROM
  payments p
  INNER JOIN (
      SELECT
        P_Type,
        100 - SUM(P_AmtPerc) AS remaining_perc,
        SUM(case P_AmtPerc when 0 then 1 else 0 end) as num_zero
      FROM payments
      GROUP BY P_Type
      HAVING SUM(P_AmtPerc) < 100
        AND SUM(case P_AmtPerc when 0 then 1 else 0 end) > 0
    ) r
    ON p.P_Type = r.P_Type
WHERE p.P_AmtPerc = 0

您将识别内联视图与目前发布的其他两个答案中提供的查询类似。它为每种付款类型计算剩余的待分配百分比和分割它的付款行数,过滤掉已经分配了(至少)100%付款的任何付款类型,或者没有任何行的付款类型指定零支付。

查询的其余部分是专有的SQL Server语法,基本上是通过视图更新表。它仅更新那些P_AmtPerc = 0 在内联视图中具有相应行的行。特别是,如果有一种付款类型,其记录的付款总计至少为100,但也有一些零的付款,那么现在更新该付款类型的行。它忽略了任何非零支付百分比,将零余额支付之间的余额分开,而不是使它们与第一笔付款相匹配。