sql >> Database >  >> RDS >> Sqlserver

Haal de bijgewerkte waarde van de vorige rij op met behulp van LAG Zonder recursieve CTE te gebruiken

De prestaties hier lijden aan recursieve CTE. CTE op zich is gewoon syntactische suiker.

Alleen voor deze specifieke voorbeeldgegevens werkt dit zonder recursie:

Declare @Tbl as Table(SNO Int,Credit Money,Debit Money,PaidDate Date)
Insert into @Tbl
SELECT * FROM (VALUES (1,0,12,'7Jan16'), (2,10,0,'6Jan16'), (3,15,0,'5Jan16'), (4,0,5,'4Jan16'), (5,0,3,'3Jan16'), (6,0,2,'2Jan16'), (7,20,0,'1Jan16')) AS X(SNO,Credit,Debit,PaidDate);

With CTE1 As (
    Select *
      , CASE WHEN Credit > 0 THEN LEAD(1 - SIGN(Credit), 1, 1) OVER (ORDER BY SNO) ELSE 0 END As LastCrPerBlock
    From @Tbl
), CTE2 As (
    Select *
      , SUM(LastCrPerBlock) OVER (ORDER BY SNO DESC ROWS UNBOUNDED PRECEDING) As BlockNumber
    From CTE1
), CTE3 As (
    Select *
      , SUM(Credit - Debit) OVER (PARTITION BY BlockNumber) As BlockTotal
      , SUM(Credit - Debit) OVER (PARTITION BY BlockNumber ORDER BY SNO ROWS UNBOUNDED PRECEDING) As BlockRunningTotal
    From CTE2
)
Select SNO, Credit, Debit
  , CASE WHEN BlockRunningTotal < 0 THEN -BlockRunningTotal ELSE 0 END As TotalDebit
  , CASE WHEN BlockRunningTotal > 0 THEN CASE WHEN Credit < BlockRunningTotal THEN Credit ELSE BlockRunningTotal END ELSE 0 END As Amount
  , PaidDate
From CTE3
Order By SNO;

Dit kan helpen bij het evalueren van de prestaties, maar het zal mislukken als in een bloktotaal van Debit s overschrijdt het totaal van Credit s. Als BlockTotal negatief is, dan moet het worden samengevoegd met een of meerdere volgende blokken en dat kan niet zonder iteratie of recursie.

In het echte leven zou ik CTE3 in een tijdelijke tabel dumpen en eroverheen gaan door blokken samen te voegen totdat er geen negatieve BlockTotal meer zijn v.



  1. Hoe te weten of de DELETE-query echt een rij verwijdert, met behulp van PDO

  2. Converteer SQL-query om set-operators te gebruiken

  3. SQL Server Profiler gebruiken | Problemen met SQL Server-prestaties oplossen -5

  4. SQL SELECT-instructie