【问题标题】:Ledger Report Logic in Stored Procedure存储过程中的账本报表逻辑
【发布时间】:2017-03-07 07:23:09
【问题描述】:

我有一个名为“Patient Ledger Report”的存储过程,我需要在其中显示患者的日常交易详细信息和余额。我从下面的代码中为您提供了一个样本数据,这些数据是如何插入到我的临时代码中的我的 sp 中的表。

create table #Patient_ledger (PATIENT_NAME varchar(250),PATIENT_NBR bigint,BILLNO varchar(250),BILLAMOUNT bigint,
PAID_AMOUNT bigint)

Insert into #Patient_ledger (Patient_name ,Patient_nbr ,billno ,billamount ,
paid_amount )

select 'ABC',1,'DUE_BILL_ABC_1',100,50
union all
select 'ABC',1,'DUE_BILL_ABC_2',160,90
UNION ALL
select 'ABC',1,'DEPOSIT_BILL_ABC',0,60
UNION ALL
select 'XYZ',2,'DEPOSIT_BILL_XYZ',0,70
UNION ALL
select 'XYZ',2,'DUE_BILL_XYZ_1',100,30

SELECT * FROM #Patient_ledger

Drop table #Patient_ledger

我想如何在我的报告中显示数据。

 PATIENT_NUMBER   BILLNO         BILLAMOUNT  PAID_AMOUNT  BALANCE

    1          DUE_BILL_ABC_1      100         50            50  --(100-50)     
    1          DUE_BILL_ABC_2      160         90            120  --(160-90 +50(Here 50 is prev balance amount of same patient))
    1          DEPOSIT_BILL_ABC     0          40            80 ---( 120-40=80)
    2          DEPOSIT_BILL_XYZ     0          70            0        
    2          DUE_BILL_XYZ_1      100         30            0  --Here Balance is zero because  patient has deposited some      
                                                                 --amount before bill (70-100+30=0)      

Note: Balance amount should deduct when deposits are paid by that particual patient.

【问题讨论】:

  • 为什么第 4 行余额为 0 ?应该是 80-70=10
  • 是否有订购这些记录的日期或身份?
  • 你需要有一个像账单日期这样的列来订购,你有没有这样的列
  • @Matej 在实际的sp数据中有一些不同表的标识列和日期列按数据排序
  • @Matej 它完全符合我的需要-:)

标签: sql-server sql-server-2008 tsql sql-server-2005 sql-server-2014


【解决方案1】:

我已经尝试过如下它可能对你有帮助

SELECT Patient_nbr,
       billno,
       billamount,
       PAID_AMOUNT,
       CASE
         WHEN RNO > 1 THEN Sum(billamount - PAID_AMOUNT)
                             OVER(
                               PARTITION BY Patient_nbr
                               ORDER BY RNO)
         ELSE Iif(( billamount - PAID_AMOUNT ) < 0, 0, billamount - PAID_AMOUNT)
       END
FROM   (SELECT *,
               Row_number()
                 OVER(
                   PARTITION BY Patient_nbr
                   ORDER BY Patient_nbr) AS RNO
        FROM   #Patient_ledger) A 

【讨论】:

    【解决方案2】:

    如果您还可以在其中放置顺序鉴别器,它可能看起来像这样:(我还认为一个 PATIENT_NBR 可能有更多的 DUE/DEPOSITS)

    IF OBJECT_ID('tempdb..#Patient_ledger') IS NOT NULL DROP TABLE #Patient_ledger
        CREATE TABLE #Patient_ledger 
        (ID INT IDENTITY, 
         PATIENT_NAME varchar(250),
         PATIENT_NBR bigint,
         BILLNO varchar(250),
         BILLAMOUNT bigint,
         PAID_AMOUNT bigint)
    
    Insert into #Patient_ledger (PATIENT_NAME ,PATIENT_NBR ,BILLNO ,BILLAMOUNT ,
    PAID_AMOUNT )
    
    select 'ABC',1,'DUE_BILL_ABC_1',100,50
    union all
    select 'ABC',1,'DUE_BILL_ABC_2',160,90
    UNION ALL
    select 'ABC',1,'DEPOSIT_BILL_ABC',0,40
    UNION ALL
    select 'XYZ',2,'DEPOSIT_BILL_XYZ',0,70
    UNION ALL
    select 'XYZ',2,'DUE_BILL_XYZ_1',100,30
    
    
    ;WITH CTE AS (
    SELECT PATIENT_NBR, 
           BILLNO,
           PAID_AMOUNT,
           BILLAMOUNT,
           BILLAMOUNT-PAID_AMOUNT AS BALANCE, 
           ROW_NUMBER() OVER (PARTITION BY PATIENT_NBR ORDER BY ID) AS RN
    FROM #Patient_ledger)
    
    SELECT a.PATIENT_NBR,
           a.BILLNO,
           a.BILLAMOUNT,
           a.PAID_AMOUNT,
           CASE WHEN ISNULL(LAG(a.BALANCE + ISNULL(x.ADDS,0)) OVER (PARTITION BY a.PATIENT_NBR ORDER BY a.RN),0) + a.BILLAMOUNT - a.PAID_AMOUNT < 0 
                THEN 0
                ELSE a.BALANCE + ISNULL(x.ADDS,0)
           END AS FINAL_BALANCE
    
    FROM CTE a
    CROSS APPLY (SELECT SUM(BALANCE) AS ADDS 
                    FROM CTE f 
                        WHERE f.PATIENT_NBR = a.PATIENT_NBR AND f.RN < a.RN) x
    

    【讨论】:

    • 我想要不使用 Lag 函数的逻辑。因为我们的客户端服务器是 2008 年的。
    【解决方案3】:

    试试这个并告诉我它是否也适用于其他示例数据。

    create table #Patient_ledger (PATIENT_NAME varchar(250),PATIENT_NBR bigint
    ,BILLNO varchar(250),BILLAMOUNT bigint,PAID_AMOUNT bigint)
    
    Insert into #Patient_ledger (Patient_name ,Patient_nbr ,billno 
    ,billamount ,paid_amount )
    
    select 'ABC',1,'DUE_BILL_ABC_1',100,50
    union all
    select 'ABC',1,'DUE_BILL_ABC_2',160,90
    UNION ALL
    select 'ABC',1,'DEPOSIT_BILL_ABC',0,40
    UNION ALL
    select 'XYZ',2,'DEPOSIT_BILL_XYZ',0,70
    UNION ALL
    select 'XYZ',2,'DUE_BILL_XYZ_1',100,30
    
    
    SELECT PATIENT_NBR PATIENT_NUMBER
        ,BILLNO
        ,BILLAMOUNT
        ,PAID_AMOUNT
        ,CASE 
            WHEN billamount = 0
                AND lag((BILLAMOUNT - PAID_AMOUNT), 1, 0) OVER (
                    PARTITION BY PATIENT_NBR ORDER BY PATIENT_NBR
                    ) = 0
                THEN 0
            ELSE SUM((BILLAMOUNT - PAID_AMOUNT)) OVER (
                    PARTITION BY PATIENT_NBR ORDER BY PATIENT_NBR ROWS UNBOUNDED PRECEDING
                    )
            END Balance
    FROM #Patient_ledger
    
    Drop table #Patient_ledger
    

    【讨论】:

    • 我想要不使用 Lag 函数的逻辑。因为我们的客户端服务器是 2008 年的。
    猜你喜欢
    • 2014-12-01
    • 1970-01-01
    • 2011-11-04
    • 2011-05-28
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-05
    相关资源
    最近更新 更多