原則:能用集合式解決,絕不使用游標。
表 student_Score(sno, cno, score, level),依分數段寫入等級:90↑=A, 80-89=B, 60-79=C, <60=D。
逐筆讀取、判斷、更新,每筆至少 2 次 I/O,N 筆資料 2N 次存取。
UPDATE student_Score SET level='D';
UPDATE student_Score SET level='C' WHERE score BETWEEN 60 AND 79;
UPDATE student_Score SET level='B' WHERE score BETWEEN 80 AND 89;
UPDATE student_Score SET level='A' WHERE score BETWEEN 90 AND 100;
缺點:高分資料列被重複更新 4 次(D→C→B→A),產生額外 I/O 與記錄檔寫入。
建立對照表 level_about(start_score, end_score, level):
INSERT INTO level_about VALUES (0, 59, 'D'), (60, 79, 'C'), (80, 89, 'B'), (90, 100, 'A');
單一陳述式完成:
UPDATE student_Score
SET level = la.level
FROM level_about la
WHERE student_Score.score BETWEEN la.start_score AND la.end_score;
優點:單次掃描、無重複更新、邏輯集中維護、擴充性佳(新增分數段只改對照表)。
需求:每日 00:00 結算,週一/週四額外結算獎金。
建立單列表 misc(days INT) 記錄運行天數,每日排程 UPDATE misc SET days=days+1。
判斷獎金日:IF @days%7=0 OR (@days-3)%7=0(第 0、3、7、10…天)。
此類確定性演算法可直接在 T-SQL 實作,無需複雜轉換。
規則:每 4000 元獎金扣 400 元作「重複消費」,滿 400 元贈 1 件商品,餘額遞延下期。
表結構:
- member(total_award, repeat_num) 累計獎金與已贈次數
- award_day 當期獎金與扣除暫存
- award_repeat 重複消費明細
- award 實發獎金
批次演算法:
1. 當期獎金先累加至 member.total_award。
2. 迴圈條件 F1:total_award >= (repeat_num+1)*4000。
3. 滿足 F1 的會員:寫入 award_repeat、member.repeat_num++,重複檢查 F1 直到無符合者。
4. 最後由 award_day 扣除本期應扣金額得實發數。
資料庫演算法優化關鍵在於:
- 熟悉業務規則與資料特徵。
- 善用集合式思維、查閱表、遞迴 CTE、窗口函數替代游標。
- 將複雜迴圈轉換為「條件篩選 + 批次更新 + 迭代收斂」模式。
隨著業務複雜度提升,演算法與 SQL 的深度融合將成為資料庫開發核心競爭力。