SQL查询使用两个表SQL Server重叠总和

时间:2015-01-22 07:36:09

标签: c# sql sql-server entity-framework

如果有人可以帮我查询,我会非常感激。

我有两张表 - PaymentsRepayments

Payments:                              Repayments:    
DATE         SUM      IS_REPAYED       DATE         SUM
01/01/15     20 000    0               05/01/15     5 000
                                       06/01/15     10 000

我需要有一个标记,显示Payment总和是否包含Repayment和,在这种情况下,如果是(5 000 + 10 000) covers 20 000,则现在不是。

但是当添加新的Repayment时,它是:

Payments:                              Repayments:    
DATE         SUM      IS_REPAYED       DATE         SUM
01/01/15     20 000    1               05/01/15     5 000
                                       06/01/15     10 000
                                       07/01/15     5 000

但是,可能会出现Repayments超过付款的情况,这表示Payment已被还款,其余5 000 (25 000 - 20 000)应计算为Repayment 下一步 Payment,即:

Payments:                              Repayments:    
DATE         SUM      IS_REPAYED       DATE         SUM
01/01/15     20 000    1               05/01/15     25 000
01/02/15     10 000    0

当新的还款到来时:

Payments:                              Repayments:    
DATE         SUM      IS_REPAYED       DATE         SUM
01/01/15     20 000    1               05/01/15     25 000
01/02/15     10 000    1               05/02/15     5 000  (or more, ex. 6 000) then 1 000 goes to the next Payment

还有一种情况,Repayment首先出现,然后下一次付款应该有一个标志:

Payments:                              Repayments:    
DATE         SUM      IS_REPAYED       DATE         SUM
                                       01/03/15     30 000
05/03/15     30 000     1              

那么当我使用付款/还款声明的当前情况在特定时间查询表时,如何获得此IS_REPAYED标志?我知道我可以在我的应用程序中为该标志创建一个逻辑,它会是一个更好的解决方案吗?

要获得上面显示的视图,我使用FULL OUTER JOIN

SELECT t1.DATE, t1.SUM, NULL AS IS_REPAYED /*?*/, t2.DATE, t2.SUM
FROM 
(   (SELECT t1.*, row_number() OVER (ORDER BY DATE) as seqnum
    FROM Payments t1
    ) t1 
   FULL OUTER JOIN
   (SELECT t2.*, row_number() OVER (ORDER BY DATE) as seqnum
   FROM Repayments t2
   ) t2
ON t1.seqnum = t2.seqnum
)

2 个答案:

答案 0 :(得分:0)

嗯,我认为您可以通过以下sql查询实现这一目标

SELECT t1.DATE, SUM(t1.SUM), SUM(t1.SUM) = SUM(t2.SUM) AS IS_REPAYED, t2.DATE, SUM(t2.SUM)
FROM Payments t1 FULL OUTER JOIN Repayments t2 ON t1.DATE = t2.DATE
GROUP BY t1.DATE

答案 1 :(得分:0)

<强> 1。当还款金额小于或等于该月的付款金额时,将IS_REPAYED更新为PAYMENTS表中的0或1。

UPDATE PAYMENTS SET IS_REPAYED = S.IS_REPAYED
FROM
(
    SELECT P.[DATE],CASE WHEN  R.[SUM] = P.[SUM] THEN 1 ELSE 0 END IS_REPAYED
    FROM PAYMENTS P 
    JOIN 
    (
        SELECT CAST(DATEADD(month, DATEDIFF(month, 0, [DATE]), 0)AS DATE) [DATE],  SUM([SUM]) [SUM]
        FROM REPAYMENTS
        GROUP BY CAST(DATEADD(month, DATEDIFF(month, 0, [DATE]), 0)AS DATE)
    )R
    ON DATEPART(MONTH,P.[DATE]) = DATEPART(MONTH,R.[DATE]) AND R.[SUM] <= P.[SUM]
)S
WHERE PAYMENTS.[DATE]=S.[DATE]
  • Click here查看结果(还款金额小于付款金额)
  • Click here查看结果(还款金额等于付款金额)

<强> 2。当reaymant金额大于该月的付款金额时,将IS_REPAYED更新为PAYMENTS表中的0或1,并插入两个表。

在内部查询中查找每月数据的总和和组,然后将其与付款表进行比较。由于我们需要此数据以进一步插入PAYMENTSREPAYMENTS表,因此我们使用临时表。

SELECT P.[DATE] PAYDATE ,P.[SUM] PAYSUM ,R.[DATE] REDATE,R.[SUM] RESUM
INTO #NEWTABLE
FROM PAYMENTS P 
JOIN 
(
    SELECT  CAST(DATEADD(month, DATEDIFF(month, 0, [DATE]), 0)AS DATE) [DATE],  SUM([SUM]) [SUM]
    FROM REPAYMENTS
    GROUP BY  CAST(DATEADD(month, DATEDIFF(month, 0, [DATE]), 0)AS DATE)
)R
ON DATEPART(MONTH,P.[DATE]) = DATEPART(MONTH,R.[DATE]) AND R.[SUM] > P.[SUM]

现在我们找到差异并插入REPAYMENTS

INSERT INTO REPAYMENTS
SELECT DATEADD(DAY,1,PAYDATE) [DATE], (RESUM-PAYSUM) REAMOUNT
FROM #NEWTABLE

同样我们找到差异并插入PAYMENTS

INSERT INTO PAYMENTS    
SELECT DATEADD(MONTH,1,PAYDATE) [DATE], (RESUM+(RESUM-PAYSUM))-PAYSUM REAMOUNT,1
FROM #NEWTABLE

由于REPAYMENTS表中的值大于PAYMENTS表,我们直接从临时表中将表的值更新为1.

UPDATE PAYMENTS SET ISREPAYED = 1
FROM
(
    SELECT PAYDATE FROM  #NEWTABLE
)N
WHERE PAYMENTS.[DATE]=N.PAYDATE