Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Nhận giá trị cập nhật hàng trước bằng LAG mà không cần sử dụng CTE đệ quy

Hiệu suất ở đây đang bị đệ quy CTE. Bản thân CTE chỉ là một đường cú pháp.

Chỉ đối với dữ liệu mẫu cụ thể này, nó hoạt động mà không cần đệ quy:

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;

Điều này có thể giúp đánh giá hiệu suất, nhưng sẽ không thành công nếu trong bất kỳ khối nào có tổng số Debit s vượt quá tổng số Credit S. Nếu BlockTotal là số âm thì nó phải được hợp nhất với một hoặc một số khối sau và không thể thực hiện được điều đó nếu không lặp lại hoặc đệ quy.

Trong cuộc sống thực, tôi sẽ kết xuất CTE3 vào bảng tạm thời và xoay vòng qua nó để hợp nhất các khối cho đến khi không còn BlockTotal âm nào nữa s.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Gửi dữ liệu qua email trong T-SQL

  2. Nhập nhiều tệp CSV vào SQL Server từ một thư mục

  3. Tạo các nhóm ngày liên tiếp đáp ứng một tiêu chí nhất định

  4. Nhà cung cấp đường ống được đặt tên:Không thể mở kết nối với SQL Server [53]

  5. SQL Server - Xóa tất cả các ký tự ASCII không in được