AI & Data Dreamers練功房
寶箱片場規則
QUERY GATES・資料庫關卡・高階・3 題

SQL 高階・冪等寫入與缺漏偵測

這一頁是題幹試閱;登入/註冊後每題可以在瀏覽器裡執行、對答案,第一次交對 +10 XP。

  1. 01

    冪等寫入

    困難

    資料管線每天把廠商報價寫進 food 表,同一份資料可能因為重跑而寫入兩次。請寫出「重跑也不會產生重複或錯誤」的寫入 SQL:

    1. 新增一筆食品:id 'CK006'、名稱 '牛軋糖'、到期日 '2019-12-31'、產地 'TW'、價格 200、種類 '點心'
    2. 把 'CK001' 的價格更新為 270(其他欄位維持原值)

    兩筆都要用 INSERT … ON CONFLICT(id) DO UPDATE SET … 的寫法(UPSERT),第 2 筆寫入完整的 CK001 資料(名稱 '曲奇餅乾'、到期日 '2019-01-10'、產地 'TL'、種類 '點心')。

    本題執行時會把你的 SQL「連續跑兩次」,再印出 food 總筆數與 CK001、CK006 兩筆資料。

    資料表 food:id 編號(文字,主鍵)、name 名稱(文字)、expiredate 到期日(文字,格式 'YYYY-MM-DD')、placeid 產地編號(文字)、price 價格(整數)、catalog 種類(文字)。

    作答登入後可作答
  2. 02

    冪等寫入

    中等

    對 TaiwanStockPrice 寫入兩筆 2330 的資料,要求重跑多次結果都一樣:

    | stock_id | date | open | max | min | close | Trading_Volume |

    |---|---|---|---|---|---|---|

    | 2330 | 2026-01-05 | 995 | 1010 | 990 | 1002 | 21000 |

    | 2330 | 2026-01-21 | 1085 | 1100 | 1080 | 1090 | 31000 |

    第一筆主鍵已存在(原 close 1000、量 20000),必須更新;第二筆是新資料。請用 sqlite 的 INSERT ... ON CONFLICT(stock_id, date) DO UPDATE SET ...(更新 open、max、min、close、Trading_Volume 五欄,用 excluded.<欄位> 取新值)。執行後會自動列出這兩筆的 stock_id、date、close、Trading_Volume。

    MySQL 寫法差異:INSERT ... ON DUPLICATE KEY UPDATE close = VALUES(close), ...(8.0.20 以後建議改用 INSERT ... AS new ON DUPLICATE KEY UPDATE close = new.close)。

    資料表 TaiwanStockPrice(與課程第 6 章的股價表同構):stock_id 股票代號(文字)、date 交易日(文字,'YYYY-MM-DD')、open、max、min、close(實數)、Trading_Volume 成交量(整數);複合主鍵 (stock_id, date)。資料含 2330 與 2317 兩檔、2026-01-05 至 2026-01-20 的交易日。

    作答登入後可作答
  3. 03

    缺漏交易日偵測

    中等

    第 17 章的每日資料線要檢查「哪一天沒抓到」。請找出每支股票在 trading_calendar 中有、但 TaiwanStockPrice 中沒有的交易日,欄位依序 stock_id、date,依 stock_id、date 排序。

    做法:先用 CROSS JOIN 產生「每支股票 × 每個交易日」的完整組合,再 LEFT JOIN 股價表找出 NULL。

    資料表 TaiwanStockPrice(與課程第 6 章的股價表同構):stock_id 股票代號(文字)、date 交易日(文字,'YYYY-MM-DD')、open、max、min、close(實數)、Trading_Volume 成交量(整數);複合主鍵 (stock_id, date)。資料含 2330 與 2317 兩檔、2026-01-05 至 2026-01-20 的交易日。

    資料表 trading_calendar:date 交易日(文字,主鍵),列出區間內所有開盤日。

    作答登入後可作答