在一卡通消費系統中,經常需要統計各部門員工月卡的餘額總和。由於消費記錄分散在 T_ConsumeRec(消費明細)與 T_CashRec(儲值/取款明細)兩張表,且需取每位持卡人截至指定月份的最新一筆記錄餘額,再按部門彙總,邏輯較為複雜。
UNION ALL 將消費與儲值記錄合併,統一欄位為 CustomerID, OpCount, OddFare, OpDt。CustomerID 分組,找出 OpDt <= 目標月份 且 OpCount 最大的那一筆,即為該月結餘依據。CustomerID + OpCount 關聯回合併流水,拿到 OddFare(操作後餘額)。T_Customers.Account 前 2 碼為一級部門代碼,與 T_Department.DpCode1 關聯,最後 GROUP BY DpCode1 求和。SELECT dp.dpname1 AS 部門,
cust_dp_SumOddfre.sum_oddfare AS 當月卡總餘額
FROM (
SELECT T_Department.DpCode1,
SUM(custid_SumOddfare_group.sum_oddfare) AS sum_oddfare
FROM (
SELECT l2.CustomerID,
SUM(r1.oddfare) AS sum_oddfare
FROM (
SELECT CustomerID, MAX(OpCount) AS max_opcount
FROM (
SELECT CustomerID, OpCount,
CAST(YEAR(OpDt) AS varchar) + '-' +
CAST(MONTH(OpDt) AS varchar) + '-01' AS dt
FROM T_ConsumeRec
UNION ALL
SELECT CustomerID, OpCount,
CAST(YEAR(CashDt) AS varchar) + '-' +
CAST(MONTH(CashDt) AS varchar) + '-01' AS dt
FROM T_CashRec
) l1
WHERE dt <= '2005-06-01' -- 可用參數傳遞
GROUP BY CustomerID
) l2
INNER JOIN (
SELECT CustomerID, OpCount, OddFare
FROM T_ConsumeRec
UNION ALL
SELECT CustomerID, OpCount, OddFare
FROM T_CashRec
) r1 ON l2.CustomerID = r1.CustomerID
AND r1.OpCount = l2.max_opcount
GROUP BY l2.CustomerID
) custid_SumOddfare_group
INNER JOIN T_Customers
ON custid_SumOddfare_group.CustomerID = T_Customers.CustomerID
INNER JOIN T_Department
ON SUBSTRING(T_Customers.Account, 1, 2) = T_Department.DpCode1
AND SUBSTRING(T_Customers.Account, 3, 2) = T_Department.DpCode2
AND SUBSTRING(T_Customers.Account, 5, 3) = T_Department.DpCode3
GROUP BY T_Department.DpCode1
) cust_dp_SumOddfre
INNER JOIN (
SELECT DISTINCT DpCode1, DpName1
FROM T_Department
) dp ON dp.DpCode1 = cust_dp_SumOddfre.DpCode1;
CustomerID, OpCount, OpDt, OddFare 等。CustomerID, OpCount, CashDt, OddFare 等。Account 編碼規則為 DpCode1(2) + DpCode2(2) + DpCode3(3)。(DpCode1, DpCode2, DpCode3)。T_ConsumeRec、T_CashRec 上建立 (CustomerID, OpDt, OpCount) 覆蓋索引。@TargetMonth DATE 參數,避免字串拼接注入風險。