SQL 分類多數篇的查詢跑在同一組表上:一家小書店的三張表,顧客、訂單、評價。談代價與計畫的那幾篇需要大量資料,另外造自己的表並在篇內標明。

建表語句與初始資料

1CREATE TABLE 顧客 (顧客編號 INT, 姓名 TEXT);
2CREATE TABLE 訂單 (訂單編號 INT, 顧客編號 INT, 下單日 TEXT, 金額 INT);
3CREATE TABLE 評價 (評價編號 INT, 訂單編號 INT, 星等 INT);
4
5INSERT INTO 顧客 VALUES (1,'佳穎'), (2,'宗翰'), (3,'雅文');
6INSERT INTO 訂單 VALUES (101,1,'2026-03-02',300), (102,1,'2026-03-09',500);
7INSERT INTO 評價 VALUES (9001,101,5);

三個顧客裡只有佳穎下過單,她的兩張訂單裡只有第一張被評價過。空缺是刻意留的——外連接、NULL 與條件放哪裡的差別,全部要靠這些空缺才顯示得出來。

RIGHT JOIN 與 FULL OUTER JOIN 是後來才加進 SQLite 的,舊版回語法錯誤;遇到的話先用 sqlite3 --version 對一下手上這一份。

各篇輸出所用的引擎版本與閱讀輸出的約定

各篇的輸出都是實際跑出來的,多數在 SQLite 3.51 上。談權限的那一篇整篇在 PostgreSQL 18;比較各家行為的那幾篇另外用到 MySQL 8.4 與 DuckDB v0.10.3,牽涉到各家行為不同的地方都標明是哪一個引擎與哪一版。

錯誤訊息:引擎的錯誤訊息會隨版本改措辭,所以各篇引的那些字串是對照用的,判讀看它拒絕了什麼、不看它怎麼說。

列序:各篇印出來的結果集為了對照固定了列序,而沒有 ORDER BY 的查詢實際回來的順序沒有保證(SQL.11 查詢結果的列序:沒有 ORDER BY 時的來源與 ORDER BY 的規定範圍 拿同一段查詢在建索引前後回不同順序示範這一條)。

資料的增刪:有幾篇會在共用資料上增刪幾列以顯示某個效果,那些改動只在該篇之內成立——換一篇之前回到這一頁最上面那組初始資料。