iT邦幫忙

2026 iThome 鐵人賽

DAY 8
0
Claude AI

Claude Code陪跑:一人開發者的訂閱制SaaS架構與十大地雷實戰記系列 第 8

# Day 8|地雷#5:同一天多筆子類別資料,排序取最新一筆時悄悄拿錯

  • 分享至 

  • xImage
  •  

事故現場

一個「跟上一期資料比較變化幅度」的功能,偶爾會顯示出離譜的變化率——明明實際變化不到 1%,畫面上卻顯示出好幾倍的跳動。而且無法穩定重現:同一筆資料,有時對有時錯。

根因解剖

問題出在一張「一個日期底下有多筆記錄」的表。這張表按日期存放資料,但同一天會有多筆——因為同一天底下還細分不同的子類別(不同批次、不同細分市場,這類結構在很多領域都有)。

要「取最近兩天的資料來比較」,直覺的寫法是:

SELECT date, value FROM records
ORDER BY date DESC
LIMIT 2;

這段 SQL 的問題:ORDER BY date 在同一天有多筆時,那幾筆的相對順序是未定義的——資料庫想給你哪筆就給你哪筆,取決於寫入順序、索引狀態、查詢計畫。所以 LIMIT 2 拿到的可能是「昨天的甲類 + 今天的甲類」(對),也可能是「今天的甲類 + 今天的乙類」(錯——你以為在算跨日變化,其實在算兩個子類別之間的差異)。

「有時對有時錯」的謎底就是這個:你把一個未定義行為當成了穩定行為在依賴。

防線怎麼蓋

修法是讓查詢明確講清楚要什麼,不留任何未定義空間:

SELECT date, value FROM records
WHERE category = :cat          -- 鎖定子類別
ORDER BY date DESC
LIMIT 2;

以及更根本的檢查習慣,寫進了地雷清單:任何「取最新一筆」的邏輯,動手前先回答——這張表在同一個排序鍵值下,可能存在超過一筆嗎? 如果答案是「可能」,排序條件就必須完整到能唯一決定結果。

這條雷的深層教訓

它教的其實是一個資料庫的基本觀念,但用慘痛的方式:SQL 不會拒絕語意不完整的查詢,它會用任意行為填補你沒講清楚的部分。 ORDER BY 沒排到的維度、GROUP BY 之外被 ANY_VALUE 掉的欄位、沒有 ORDER BYLIMIT——這些地方資料庫都在替你做你不知道的決定。

順帶一提,這條也是 agent 特別容易踩的雷:對不熟悉這張表結構的人(或 AI)來說,ORDER BY date LIMIT 2 是再自然不過的寫法。把「這張表同一天有多筆」這個事實寫進地雷清單之後,agent 產生的查詢就會自帶子類別條件——又一次驗證了 Day 3 的論點:專案特有的資料形狀知識,不寫下來就等著被重新踩一次。


上一篇
# Day 7|地雷#4:同一個欄位,兩張表用不同單位記錄,混用差1000倍還不報錯
下一篇
# Day 9|地雷#6:第三方 API 的「基準值」不可信,自己從序列資料重算
系列文
Claude Code陪跑:一人開發者的訂閱制SaaS架構與十大地雷實戰記16
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言