【问题标题】:Adjusting payments against balances some id wise明智地根据余额调整付款
【发布时间】:2017-01-31 10:36:25
【问题描述】:

我在表格中有Store_IDs 的总付款,需要针对transactions_ids 为各自的store_ids 结算/调整付款。

可以按如下方式创建表:

--- CREATE STORE_PAYMENTS TABLE--- CONTAINS RECEIVABLE AGAINST RECEIPTS NOS FOR STROES-------
CREATE TABLE DBO.STORE_PAYMENTS
 (STORE_ID VARCHAR(10) NOT NULL,
 RECEIPT_NO VARCHAR(10) NOT NULL,
 RECEIVABLE INT NOT NULL,
 PAYMENT_ADJUSTED INT NOT NULL,
 BALANCE INT NOT NULL)
 GO

INSERT INTO DBO.STORE_PAYMENTS
(STORE_ID,RECEIPT_NO,RECEIVABLE,PAYMENT_ADJUSTED,BALANCE)
VALUES
('STR1',1,100,0,0),
('STR1',2,200,0,0),
('STR1',3,300,0,0),
('STR2',1,100,0,0),
('STR2',2,100,0,0),
('STR2',3,50,0,0),
('STR3',1,0,0,0),
('STR3',2,150,0,0),
('STR3',3,300,0,0)

---- CREATE STORE_BALANCE TABLE --- CONTAINS INFORMATION OF IN HAND PAYMENTS -----------------
CREATE TABLE DBO.STORE_BALANCE
 (STORE_ID VARCHAR(10) NOT NULL,
 PAYMENTS INT NOT NULL)
 GO

INSERT INTO DBO.STORE_BALANCE
(STORE_ID,PAYMENTS)
VALUES
('STR1',600),
('STR2',700),
('STR3',300)

SELECT * FROM DBO.STORE_BALANCE
SELECT * FROM DBO.STORE_PAYMENTS

调整支付的顺序可能是基于RECEIPT_NO order或rowid。

突出显示的列中的必需输出:

【问题讨论】:

  • 将示例数据共享为 DDL + DML 很棒,但您还应该解释所需输出的逻辑,并展示您已经尝试过的内容。
  • 为什么 str2 在 250 的账单上支付了 700?
  • 亲爱的 Zohar,我尝试在 SQL 中应用会计中使用的 FIFO 方法,但这对于这个问题来说太复杂了。
  • STR1,STR2... 是分配给不同商店的 ID,这些商店可能在特定时间点之前累积付款。付款可能少于未付总额,也可能多于未付金额(针对多张发票)。有时,我们需要根据未付发票/收据调整付款。我们必须根据可用付款关闭尽可能多的收据。

标签: sql-server tsql balance


【解决方案1】:
BEGIN TRAN

 --CREATE #STORE_PAYMENTS TABLE--- CONTAINS RECEIVABLE AGAINST RECEIPTS NOS FOR STROES------- 
 CREATE TABLE #STORE_PAYMENTS (STORE_ID VARCHAR(10) NOT NULL, RECEIPT_NO VARCHAR(10) NOT NULL, RECEIVABLE INT NOT NULL, PAYMENTS INT NOT NULL, BALANCE INT NOT NULL)
  GO

INSERT INTO #STORE_PAYMENTS (STORE_ID,RECEIPT_NO,RECEIVABLE,PAYMENTS,BALANCE)
SELECT 'STR1',1,100,0,0  UNION ALL
SELECT 'STR1',2,200,0,0  UNION ALL
SELECT 'STR1',3,300,0,0  UNION ALL
SELECT 'STR2',1,200,0,0  UNION ALL
SELECT 'STR2',2,300,0,0  UNION ALL
SELECT 'STR2',3,400,0,0  UNION ALL
SELECT 'STR3',1,0,0,0 UNION ALL
SELECT 'STR3',2,150,0,0 UNION ALL
SELECT'STR3',3,300,0,0

--CREATE STORE_BALANCE TABLE --- CONTAINS INFORMATION OF IN HAND PAYMENTS ----------------- 

CREATE TABLE #STORE_BALANCE (STORE_ID VARCHAR(10) NOT NULL, PAYMENTS INT NOT NULL,TMP_PAYMENTS INT NOT NULL) 

INSERT INTO #STORE_BALANCE 
SELECT 'STR1',500,500 UNION ALL
SELECT 'STR2',700,700 UNION ALL
SELECT 'STR3',300,300

SELECT  ROW_NUMBER()Over(Order by Store_ID)RowNum,* INTO #T FROM #STORE_BALANCE --Order by RowNum desc
SELECT DENSE_RANK()OVER(Order by STORE_ID)RANK, ROW_NUMBER()Over(Order by Store_ID)RowNum, * INTO #TT FROM #STORE_PAYMENTS

Declare @strt INT ,@End INT
SELECT TOP 1  @strt=RowNum FROM #t
SELECT @End=MAX(RowNum) FROM #t

While @strt<=@End
Begin 
    DECLARE @RANK INT=1,@Rownum INT,@Payments INT,@RECEIVABLE INT,@Total_RECEIVABLE  INT
    SELECT  @Rownum=MAX(RECEIPT_NO)FROM #TT WHERE  RANK=@strt

                 WHILE @RANK<=@Rownum
                     BEGIN

                             SELECT @Payments=Tmp_Payments FROM #T WHERE RowNum=@strt
                             SELECT @RECEIVABLE=RECEIVABLE  FROM #TT WHERE RANK=@strt AND RECEIPT_NO =@RANK 

                                 IF @Payments >= @RECEIVABLE
                                         Begin 

                                             UPDATE #TT SET PAYMENTS=@RECEIVABLE  WHERE RANK=@strt AND RECEIPT_NO = @RANK

                                             UPDATE  #T SET TMP_PAYMENTS=@Payments-@RECEIVABLE 
                                                     FROM #t Inner Join #tt ON #t.RowNum=#TT.RANK
                                                     WHERE  RECEIPT_NO=@RANK AND RANK=@strt

                                END ELSE BEGIN

                                                 UPDATE #TT SET PAYMENTS =@Payments WHERE RANK=@strt AND RECEIPT_NO = @RANK

                                                 SELECT @Total_RECEIVABLE=SUM(Payments) FROM #TT WHERE RANK=@strt      

                                                 UPDATE  #T SET TMP_PAYMENTS =  @Total_RECEIVABLE-@Payments
                                                         FROM #t Inner Join #tt ON #t.RowNum=#TT.RANK
                                                         WHERE RANK=@strt AND RECEIPT_NO=@RANK 

                                 END
                                -- Select * from #TT WHERE RANK=@strt AND RECEIPT_NO = @RANK 
                                SET @RANK=@RANK+1
                     END

    SET @strt=@strt+1 
END

    UPDATE #STORE_PAYMENTS SET PAYMENTS=T.PAYMENTS,BALANCE=T.RECEIVABLE-T.PAYMENTS
    FROM #STORE_PAYMENTS S INNER JOIN #TT T ON S.STORE_ID=T.STORE_ID AND S.RECEIPT_NO=T.RECEIPT_NO 

    SELECT * FROM #STORE_PAYMENTS

ROLLBACK TRAN

【讨论】:

  • 感谢 Alfaiz,我被困在了可以完成的方式中,并且您的解决方案有效。您提供的答案也很清楚。竖起大拇指!
猜你喜欢
  • 2013-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-31
  • 1970-01-01
  • 1970-01-01
  • 2020-01-28
  • 1970-01-01
相关资源
最近更新 更多