Skip to content

第 3 站练习答案 ​

← 本站索引

键集分页 ​

sql
SELECT order_id, status, total_amount, created_at
FROM sales_order
WHERE (created_at, order_id) < ('2026-01-01 00:00:00.000000', 100)
ORDER BY created_at DESC, order_id DESC
LIMIT 20;

复合比较的列顺序必须与排序一致。

NULL 安全反连接 ​

sql
SELECT c.customer_id
FROM customer AS c
WHERE NOT EXISTS (
  SELECT 1 FROM sales_order AS o
  WHERE o.customer_id = c.customer_id
);

NOT EXISTS 以相关条件判断是否存在,不会被子查询结果中的 NULL 污染。

乐观更新 ​

sql
UPDATE sales_order
SET status = 'cancelled', version_no = version_no + 1
WHERE order_id = 1
  AND status = 'paid'
  AND version_no = 1;

调用方必须检查受影响行数;零行意味着状态或版本不再满足前置条件。

加码题解:安全写入与分页 ​

sql
UPDATE orders
SET status = 'CANCELLED'
WHERE id = 42 AND status = 'PENDING';
SELECT ROW_COUNT();

关键推理 ​

条件写入把并发状态判断交给数据库,ROW_COUNT 是调用方的事实依据。

可替代方案 ​

大表列表使用 created_at + id 的 keyset cursor。

典型错误 ​

无 WHERE 更新、按非唯一时间字段 offset 分页、忽略警告和自动提交。

复盘时请附上版本、隔离级别、执行计划或恢复位置中的相关证据;没有证据的“看起来正确”不算完成。

用心记录每一步成长