SQL 核心速查

SQLite 3.45.1 常用语句速查,涵盖筛选、连接、分组、窗口、数据写入、模式变更、事务和查询计划检查。

SQLite 3.45.1 打印为 1 页
下载 .md

读取并整理行

SELECT order_id, total FROM orders; 从每行中只返回指定列
SELECT DISTINCT customer_id FROM orders; 删除投影结果中的重复行
SELECT customer_id, total AS order_total FROM orders; 明确命名结果列
SELECT * FROM orders ORDER BY total DESC NULLS LAST, order_id; 按总额倒序排列,把空值放在末尾并稳定处理并列
SELECT * FROM orders ORDER BY created_at DESC, order_id DESC LIMIT 20 OFFSET 40; 跳过排序后的前 40 行,再返回至多 20 行
SELECT CAST(total AS REAL) FROM orders; 把每个值转换为 SQLite 的实数存储类

筛选与处理空值

SELECT * FROM orders WHERE status = 'paid' AND total >= ?1; 用绑定的最低值筛选,避免拼接 SQL
SELECT * FROM orders WHERE shipped_at IS NULL; IS NULL 匹配缺失值
SELECT * FROM orders WHERE customer_id IN (1, 3, 5); 匹配显式列表中的任意值
SELECT * FROM orders WHERE created_at >= '2026-09-01' AND created_at < '2026-10-01'; 用左闭右开范围筛选九月的时间戳
SELECT COALESCE(discount, 0) FROM orders; 在结果中用零替换空折扣
SELECT CASE WHEN total >= 100 THEN 'large' ELSE 'small' END FROM orders; 按顺序匹配条件并映射每一行

连接与存在性判断

SELECT o.order_id, c.name FROM orders AS o JOIN customers AS c ON c.customer_id = o.customer_id; 只保留有匹配客户的订单
SELECT c.name, o.order_id FROM customers AS c LEFT JOIN orders AS o ON o.customer_id = c.customer_id; 保留所有客户,包括没有订单的客户
SELECT * FROM colors CROSS JOIN sizes; 生成颜色与尺寸的所有组合
SELECT * FROM orders JOIN customers USING (customer_id); 按同名列连接,并只投影一次该列
SELECT * FROM customers AS c WHERE EXISTS (SELECT 1 FROM orders AS o WHERE o.customer_id = c.customer_id); 保留至少有一笔订单的客户
SELECT * FROM customers AS c WHERE NOT EXISTS (SELECT 1 FROM orders AS o WHERE o.customer_id = c.customer_id); 保留没有匹配订单的客户,内层键可为空

分组与汇总

SELECT COUNT(*) FROM orders; 统计行数,不受行内空值影响
SELECT COUNT(shipped_at) FROM orders; 只统计发货时间非空的行
SELECT COUNT(DISTINCT customer_id) FROM orders; 统计不同的非空客户标识
SELECT customer_id, SUM(total) FROM orders GROUP BY customer_id; 返回每位客户的一个总额
SELECT customer_id, SUM(total) AS spent FROM orders GROUP BY customer_id HAVING SUM(total) >= 1000; 聚合完成后筛选分组
SELECT COUNT(*) FILTER (WHERE status = 'paid') FROM orders; 统计匹配行,不移除其他聚合的输入

合并与嵌套查询

SELECT email FROM leads UNION SELECT email FROM customers; 合并结果并删除重复行
SELECT email FROM leads UNION ALL SELECT email FROM customers; 合并结果并保留重复行
SELECT email FROM leads INTERSECT SELECT email FROM customers; 保留两个结果中都有的行
SELECT email FROM leads EXCEPT SELECT email FROM customers; 保留左侧有而右侧没有的行
SELECT * FROM orders WHERE total > (SELECT AVG(total) FROM orders); 把每行与一个标量聚合结果比较
SELECT * FROM (SELECT * FROM orders WHERE status = 'paid') AS paid_orders; 查询在 FROM 中命名的派生表

分阶段处理与递归

WITH paid_orders AS (SELECT * FROM orders WHERE status = 'paid') SELECT * FROM paid_orders; 为紧随其后的语句命名一份查询结果
WITH paid AS (SELECT * FROM orders WHERE status = 'paid'), totals AS (SELECT customer_id, SUM(total) AS spent FROM paid GROUP BY customer_id) SELECT * FROM totals; 把一个 CTE 的结果传给下一个 CTE
WITH order_totals AS (SELECT customer_id, SUM(total) AS spent FROM orders GROUP BY customer_id) SELECT c.name, t.spent FROM order_totals AS t JOIN customers AS c USING (customer_id); 把汇总后的 CTE 与明细数据连接
WITH RECURSIVE sequence(n) AS (VALUES (1) UNION ALL SELECT n + 1 FROM sequence WHERE n < 5) SELECT n FROM sequence; 用停止条件生成一到五的整数
WITH RECURSIVE tree(id, depth) AS (SELECT category_id, 0 FROM categories WHERE parent_id IS NULL UNION ALL SELECT c.category_id, t.depth + 1 FROM categories AS c JOIN tree AS t ON c.parent_id = t.id) SELECT * FROM tree; 从根节点开始遍历类别层次结构
VALUES (1, 'draft'), (2, 'paid'); 直接构造一个两行两列的结果

窗口计算

SELECT order_id, ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY created_at, order_id) AS position FROM orders; 在每个客户分区内分配稳定位置
SELECT order_id, RANK() OVER (ORDER BY total DESC) AS place FROM orders; 相同总额使用相同排名,并在之后留出空位
SELECT order_id, DENSE_RANK() OVER (ORDER BY total DESC) AS tier FROM orders; 相同总额使用相同排名,之后不留空位
SELECT order_id, LAG(total) OVER (PARTITION BY customer_id ORDER BY created_at, order_id) AS previous_total FROM orders; 读取每个分区内按顺序排列的前一个值
SELECT order_id, LEAD(total) OVER (PARTITION BY customer_id ORDER BY created_at, order_id) AS next_total FROM orders; 读取每个分区内按顺序排列的后一个值
SELECT order_id, SUM(total) OVER (PARTITION BY customer_id ORDER BY created_at, order_id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_total FROM orders; 用显式行框架计算累计总额

插入、更新与删除

INSERT INTO customers (customer_id, name, email) VALUES (?1, ?2, ?3); 用绑定值和显式列列表插入一行
INSERT INTO statuses (status_id, name) VALUES (1, 'draft'), (2, 'paid'); 用一条语句插入多行
INSERT INTO archived_orders SELECT * FROM orders WHERE created_at < '2026-01-01'; 插入查询返回的行
INSERT INTO customers (customer_id, name, email) VALUES (?1, ?2, ?3) ON CONFLICT(customer_id) DO UPDATE SET name = excluded.name, email = excluded.email; 在指定的唯一性冲突发生时插入或更新
UPDATE orders SET status = 'paid' WHERE order_id = ?1 RETURNING order_id, status; 更新匹配行并返回新值
DELETE FROM orders WHERE order_id = ?1 RETURNING order_id; 删除匹配行并返回其标识

定义模式与索引

CREATE TABLE users (user_id INTEGER PRIMARY KEY, email TEXT NOT NULL UNIQUE); 创建带标识、非空和唯一性约束的表
CREATE TABLE order_items (order_id INTEGER REFERENCES orders(order_id), sku TEXT, quantity INTEGER CHECK (quantity > 0), PRIMARY KEY (order_id, sku)); 声明复合主键、外键和正数数量
ALTER TABLE users ADD COLUMN active INTEGER NOT NULL DEFAULT 1; 添加带默认值的非空列,以兼容已有行
CREATE INDEX orders_customer_created_idx ON orders (customer_id, created_at); 为常见的等值筛选加排序访问路径建立索引
CREATE UNIQUE INDEX customers_email_idx ON customers (email) WHERE email IS NOT NULL; 只对非空电子邮件地址实施唯一性约束
DROP INDEX IF EXISTS orders_customer_created_idx; 仅在索引存在时将其删除

控制事务

BEGIN IMMEDIATE; 立即开始一个 SQLite 写事务
COMMIT; 提交并结束当前事务
ROLLBACK; 撤销当前事务
SAVEPOINT before_import; 标记一个嵌套回滚点
ROLLBACK TO before_import; 撤销保存点之后的工作,同时保留该保存点
RELEASE before_import; 删除保存点,但不结束外层事务

检查与维护

EXPLAIN QUERY PLAN SELECT * FROM orders WHERE customer_id = ?1; 显示高层查询计划,但不运行该查询
ANALYZE; 刷新所有已附加模式的查询规划器统计信息
PRAGMA optimize; 针对当前工作负载执行推荐的优化器维护
PRAGMA foreign_keys = ON; 为当前连接启用外键约束
PRAGMA table_info('orders'); 列出表的普通列及其核心属性
PRAGMA integrity_check; 扫描数据库中的结构和约束错误

向你的 AI 准确表达