存储过程中的分类帐报告逻辑

时间:2016-10-25 09:47:41

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

我有一个名为“患者分类帐报告”的存储过程,我需要显示日常交易详情和患者余额。我从下面的代码中提供了一个采样数据,数据是如何插入临时的在我的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.

3 个答案:

答案 0 :(得分: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 

答案 1 :(得分:1)

如果你能够在那里放置订单鉴别器,它可能看起来像这样:(我还认为,对于一个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

答案 2 :(得分:1)

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

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