首页 > 解决方案 > PHP 计算具有复杂标准的数据

问题描述

我有一个名为tblDueDetails的表,其中包含我的客户的所有到期详细信息。

这是我的桌子:

这是我到目前为止制作的代码:

$duesquery = "SELECT DUEDT, DUECD, STARTDT, ENDDT, DUEAMT, DUEPD FROM LLDUEDET WHERE LOANNO = '". $loanno ."' AND DUEAMT != DUEPD";
$duessql = oci_parse($conn, $duesquery);
$duesexec = oci_execute($duessql);

if($duesexec){
    while($duesrow = oci_fetch_assoc($duessql)){
        $table .= '
        <tr>
             <td>'. date('m/d/Y', strtotime($duesrow['DUEDT'])) .'</td>
             <td>'. trim($duesrow['DUECD']) .'</td>
             <td>'. date('m/d/Y', strtotime($duesrow['STARTDT'])) .'</td>
             <td>'. date('m/d/Y', strtotime($duesrow['ENDDT'])) .'</td>
             <td>'. number_format(trim($duesrow['DUEAMT']), 2) .'</td>
             <td>'. number_format(trim($duesrow['DUEPD']), 2) .'</td>
        </tr>';
    }
}

这是我的解释: - 当DUEMT不等于DUEPD
时,我需要获取所有数据。 - 但是每次有一个DUECD等于 ' PRI ' 和 ' INT ' 返回时,我需要通过添加PRIDUEAMTINTDUEAMT来计算PENALTY(请参阅表格)

我上面的 SQL 的输出:

 Due Date   |  Due |    Start Date   |  End Date |  Due Amount  |  Due Paid 
11/30/2019    PRI      10/30/2019     11/30/2019    19,546.62       0.00
11/30/2019    INT      10/30/2019     11/30/2019    10,808.38       1,062.86
11/30/2019    PEN      10/30/2019     11/30/2019    1,500.00        1,500.00
------- Insert Penalty Row Here ---------
12/30/2019    PRI      11/30/2020     12/30/2019    20,158.62       0.00
12/30/2019    INT      11/30/2020     12/30/2019    11,498.38       3,212.46
------- Insert Penalty Row Here ---------
1/03/2020     CCF      01/03/2020     01/03/2020    200.00          0.00
01/03/2020    CFR      01/03/2020     01/03/2020    729.17          0.00

我的问题是当返回数据DUECD = PRIIND时如何计算每个PENALTY

标签: phpsql

解决方案


这样的事情应该可以工作(您可以更改子查询中的惩罚计算):

我假设只有在 PRIINT记录都存在的情况下才需要计算惩罚。如果此假设不正确,并且您需要在其中一个或记录存在时计算惩罚 PRIINT可以having count(*) = 2从下面的查询中删除 。

DB Fiddle 上的演示

select LOANNO, DUEDT, DUECD, STARTDT, ENDDT, DUEAMT, DUEPD
from
(
  SELECT LOANNO, DUEDT, DUECD, STARTDT, ENDDT, DUEAMT, DUEPD
         , case 
            when DUECD = 'PRI' then 1
            when DUECD = 'INT' then 2
            else 10
           end ord
  FROM LLDUEDET
  WHERE DUEAMT != DUEPD
   union all
  select pc.LOANNO, pc.DUEDT, pc.DUECD, pc.STARTDT, pc.ENDDT, pc.DUEAMT, coalesce(pa.DUEPD, 0.0) DUEPD
         ,3 ord
  from (
    select LOANNO, DUEDT, 'PEN' DUECD, STARTDT, ENDDT, ((SUM(DUEAMT)-SUM(DUEPD)) * 30) * .1 DUEAMT
    from LLDUEDET
    WHERE DUEAMT != DUEPD
    and DUECD in ('PRI', 'INT')
    group by LOANNO, DUEDT, STARTDT, ENDDT
    having count(*) = 2
  ) pc
  left join (
    select LOANNO, DUEDT, SUM(DUEPD) DUEPD
    from LLDUEDET
    where DUECD  = 'PEN'
    group by LOANNO, DUEDT
  ) pa on pa.loanno = pc.loanno and pa.duedt = pc.duedt
) s
order by LOANNO, DUEDT, ord

推荐阅读