iT邦幫忙

2026 iThome 鐵人賽

0
ChatGPT & Codex

從 Prompt Engineering 到 Copilot / Codex 實務 30 天系列 第 18 篇

Day 18:【SQL 查詢生成】自然語言轉 SQL:讓 ChatGPT 生成多表 JOIN、聚合與窗口函數

  • 分享至 

  • xImage
  •  

完成了前三個模組的「工具設定」、「演算法解題」與「代碼重構除錯」後,今天我們正式邁入第四模組——「全端、資料庫與 API 輔助開發」。

在日常軟體開發或報表系統開發中,工程師除了撰寫後端商業邏輯,另一個極常耗費時間的任務就是與關聯式資料庫(RDBMS)打交道。簡單的單表 CRUD 很直覺,但一旦遇到「多表關聯(JOIN)」、「多維度聚合(GROUP BY)」或是「跨列統計排名(Window Functions)」時,手寫複雜 SQL 往往容易遺漏條件、邏輯錯誤,甚至寫出全表掃描(Full Table Scan)的低效語法。

今天我們就來示範:如何讓 ChatGPT 成為專屬的 DBA 助教,只要提供資料庫結構(Schema),就能用白話文精確產出高效且結構嚴謹的 SQL 查詢!


一、自然語言轉 SQL 提示詞模板(Text-to-SQL Prompting)

很多初學者問 AI「幫我查每個月買最多的會員」,卻沒給 Schema,導致 AI 只能自己猜測欄位名稱。想要產出立即可用的高質量 SQL,請使用以下標準模板:

【Text-to-SQL 提示詞範本】
請扮演資深關聯式資料庫管理員(DBA)與 SQL 專家。我目前使用的是 MySQL 8.0(或 PostgreSQL)。

以下是相關資料表的結構(Schema)與關聯:
[貼上 CREATE TABLE 語法或欄位描述清單]

商業查詢需求描述:
[用條列式清楚描述要統計或過濾的目標]

請依序提供以下內容:

  1. 完整 SQL 查詢語句:排版清晰,關鍵字大寫,並附帶關鍵邏輯註解。
  2. 語法拆解說明:說明為何使用特定的 JOIN 類型(INNER/LEFT)或窗口函數。
  3. 效能優化與索引建議:針對此查詢的 WHERE、JOIN 與 ORDER BY 欄位,推薦應建立哪些索引(Index)。
  4. 防禦性考量:若整合進後端(如 Spring Boot JPA / MyBatis),該如何防止 SQL 注入?

二、實戰案例:電商各商品分類「消費金額最高」的前 3 名會員

假設我們有以下三張資料表:

  • users(使用者表):user_id, user_name
  • orders(訂單表):order_id, user_id, total_amount, created_at
  • order_items(訂單明細):item_id, order_id, category_id, subtotal

業務目標:
「統計過去一年內,每個商品分類(category_id)中,總消費金額最高的前 3 名會員,並依分類與排名由小到大排序。」


三、AI 生成的進階 SQL 與窗口函數應用

傳統 SQL 若想取「分組內前 N 名」,通常需要寫非常痛苦且效能低落的相關子查詢(Correlated Subquery)。現代資料庫的最佳實踐是使用窗口函數(Window Functions: DENSE_RANK()):

[AI 生成的 MySQL 8.0 / PostgreSQL 查詢語句]
WITH CategoryUserSpending AS (
    -- 第一階段:計算每個會員在各個分類的總消費金額
    SELECT 
        oi.category_id,
        u.user_id,
        u.user_name,
        SUM(oi.subtotal) AS total_spent,
        -- 使用窗口函數依分類分組,依消費金額降冪排名
        DENSE_RANK() OVER (
            PARTITION BY oi.category_id 
            ORDER BY SUM(oi.subtotal) DESC
        ) AS spending_rank
    FROM users u
    INNER JOIN orders o ON u.user_id = o.user_id
    INNER JOIN order_items oi ON o.order_id = oi.order_id
    WHERE o.created_at >= DATE_SUB(NOW(), INTERVAL 1 YEAR)
    GROUP BY oi.category_id, u.user_id, u.user_name
)
-- 第二階段:從彙總結果中篩選出前 3 名
SELECT 
    category_id,
    user_id,
    user_name,
    total_spent,
    spending_rank
FROM CategoryUserSpending
WHERE spending_rank <= 3
ORDER BY category_id ASC, spending_rank ASC;

四、AI 指出的效能調優與後端安全

在產出 SQL 後,AI 特別點出了兩項工程維度的關鍵細節:

1. 複合索引推薦(Composite Index)

此查詢包含時間過濾與多表關聯,若資料量達到數千萬筆,缺乏索引將引發可怕的磁碟 I/O:

  • orders 表:建議建立 (created_at, user_id) 複合索引,讓資料庫能快速鎖定一年內的訂單並進行 JOIN。
  • order_items 表:建議建立 (order_id, category_id, subtotal) 覆蓋索引(Covering Index),免去回表查詢(Lookups)的開銷。

2. 後端防禦 SQL Injection

  • 參數化查詢(Prepared Statements):在 Java Spring Boot 或 Node.js 中串接時,絕不能用字串拼接(String Concatenation)把前端傳來的時間或分類組合進 SQL。
  • 一律使用預編譯參數佔位符(? 或 :param),確保使用者輸入不會被當作 SQL 語法解析,從根源杜絕 SQL Injection 漏洞。

今日小結與預告

今天我們掌握了利用「Text-to-SQL 模板」將模糊的商業統計需求轉化為結構嚴謹的高效 SQL。透過 CTE(Common Table Expressions)與窗口函數,大幅簡化了繁複的統計邏輯,並獲得了專業的索引建立建議。


上一篇
Day 17:【效能瓶頸診斷】揪出隱形黑洞:讓 AI 指出記憶體開銷與 CPU 快取問題
系列文
從 Prompt Engineering 到 Copilot / Codex 實務 30 天 共 18 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言