首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

SQL 依日期降序累加薪資:相關子查詢與視窗函數雙重解法

     編輯:程式設計綜合問答

資料模型

CREATE TABLE User_Salary (
    UserName NVARCHAR(200),
    Month    NVARCHAR(20),  -- 格式 'YYYY/MM'
    Salary   INT
);

需求

同一 UserName 依 Month 降序,計算「截至當月(含)的薪資累計」。

解法一:相關子查詢(通用、相容性佳)

SELECT u.*,
       (SELECT SUM(salary)
        FROM User_Salary
        WHERE UserName = u.UserName
          AND Month <= u.Month) AS 總和
FROM User_Salary u
ORDER BY u.UserName, u.Month DESC;
  • 內層查詢針對外層每一列,篩選同用戶且月份 ≤ 當月的薪資求和。
  • 適用於 MySQL 5.7、SQL Server 2012 以前、Oracle 11g 等舊版本。

解法二:視窗函數(現代標準、效能更優)

SELECT UserName, Month, Salary,
       SUM(Salary) OVER (PARTITION BY UserName ORDER BY Month DESC
                         ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS 總和
FROM User_Salary
ORDER BY UserName, Month DESC;
  • PARTITION BY UserName 分組,ORDER BY Month DESC 降序排列。
  • ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 定義視窗範圍:從分組第一列到當前列。
  • 支援:PostgreSQL 8.4+、SQL Server 2012+、Oracle 10g+、MySQL 8.0+、MariaDB 10.2+。

效能對比

指標相關子查詢視窗函數
時間複雜度O(N²) 最壞O(N log N) 排序後單掃
執行計畫Nested Loops / SpoolWindow Aggregate / Sort
大數據量(>10萬列)明顯變慢穩定高效

最佳實踐建議

  • 資料庫支援視窗函數時**優先使用**,可讀性與效能雙贏。
  • Month 欄位建議改為 DATE 或 YYYYMM 整數型別,避免字串排序陷阱(如 '2011/2' < '2011/10')。
  • 加入複合索引 (UserName, Month) 大幅加速分組排序。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved