跳到主要內容

← 返回部落格

為什麼要格式化 SQL(以及格式化工具到底做了什麼)

ORM 印出一段查詢,它以一行 300 字元的姿態落在你的 console 裡。格式化工具把那面文字牆變成有縮排、掃一眼就懂的查詢,每個子句各就各位。是同一段查詢——只是變得看得懂了。以下說明它實際在做什麼。

格式化改了什麼(又沒改什麼)

格式化只動空白、換行與縮排——以及選擇性的關鍵字大小寫。它把 SELECTFROMWHEREJOINGROUP BY 各自放到獨立的行,把欄位和條件縮排,讓巢狀結構一目了然。

它從不更動的是:你的資料表、欄位、值與邏輯。格式化後的查詢和擠成一團時回傳完全相同的結果。這也代表格式化不是驗證——它不會告訴你某個欄位拼錯了,或這段查詢實際上跑不跑得動。

方言:工具為什麼要問你用哪個資料庫

SQL 有標準,但每家資料庫都加了自己的味道,格式化工具需要知道是哪一種才能正確解析:

  • 識別字引號——MySQL 用反引號(`col`);PostgreSQL 與標準 SQL 用雙引號("col")。
  • 限制筆數——MySQL/SQLite/PostgreSQL 用 LIMIT,SQL Server 用 TOP
  • 型別轉換——PostgreSQL 的 value::int 在別處沒有對應寫法。

選錯方言,這些就會被誤判,縮排也會跑掉。貼進來前,先在 SQL 格式化選你實際用的資料庫。

關鍵字大寫:是風格,不是規則

很多團隊把關鍵字寫成大寫(SELECTFROM),讓它們和資料表、欄位名區隔開。SQL 本身對關鍵字不分大小寫,所以這純粹是可讀性慣例——格式化工具可以一鍵把整段查詢統一過來。

為什麼在本機做?

前端格式化工具在你的瀏覽器裡解析並重新輸出 SQL。你的查詢——往往透露了資料表結構與商業邏輯——永遠不會離開你的電腦。

相關工具

格式化前後對照

同一段查詢,被 ORM 壓成一行後、再格式化的樣子:

select u.id,u.name,count(o.id) as orders from users u left join orders o on o.user_id=u.id where u.active=1 group by u.id,u.name having count(o.id)>0 order by orders desc;

格式化後,結構由上而下一目了然:

SELECT
    u.id,
    u.name,
    COUNT(o.id) AS orders
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE u.active = 1
GROUP BY u.id, u.name
HAVING COUNT(o.id) > 0
ORDER BY orders DESC;

結果完全相同,但 JOIN、篩選、分組現在一眼就看得出來。

逗號放行尾還是行首

欄位常見兩種擺法:行尾逗號(每行結尾的 u.id,)或行首逗號(每行開頭的 , u.name)。行首逗號會讓版本控制的 diff 更乾淨——新增一個欄位只動一行,而不是兩行——但兩種都合法,多數格式化工具都可以選。同一個專案裡保持一致,比選哪一種更重要。

常見問題

  • 格式化會影響效能嗎? 不會。解析器會忽略無意義的空白與關鍵字大小寫,所以格式化後的查詢對引擎而言完全等價。唯一對空白敏感的,是字串常值的內容。
  • 格式化後的 SQL 該進版控嗎? 檢視表、遷移腳本、預存程序都建議這麼做——一致的風格能讓 diff 變小、審查更快。
  • 但格式化不會修好壞掉的查詢。 它只是重排文字;要抓錯,還是得靠真正的資料庫或 linter。之後要把結果匯出?看如何把 JSON 轉成 CSV 與 Excel