| SELECT id, name FROM t | 只取需要的列,避免 SELECT * |
| SELECT DISTINCT city FROM t | 去重取值 |
| SELECT COUNT(*) FROM t | 统计行数(含 NULL 行) |
| WHERE age BETWEEN 18 AND 30 | 闭区间,含两端 |
| WHERE status IN (1, 2) | 多值匹配,比多个 OR 更利于索引 |
| WHERE status NOT IN (1, 2) | 排除多值;列可为 NULL 时结果不可靠 |
| WHERE name LIKE '张%' | 前缀匹配可用索引,'%张%' 会全表扫描 |
| WHERE name NOT LIKE '%test%' | 排除包含某片段 |
| WHERE email IS NULL | 判空只能用 IS NULL,不能写 = NULL |
| WHERE email IS NOT NULL | 判非空 |
| WHERE deleted_at = '1970-01-01' | DATE/DATETIME 用字符串比较会隐式转换 |
| WHERE id = 1 AND status = 1 | 多条件 AND,等值条件放前面 |
| WHERE (a = 1 OR b = 2) AND c = 3 | OR 混合务必加括号,否则优先级出错 |
| WHERE JSON_EXTRACT(ext, '$.city') = '杭州' | MySQL 5.7+ 取 JSON 字段,简写 ext->>'$.city' |
| SELECT COUNT(*), SUM(amount) FROM t | 聚合函数忽略 NULL,COUNT(*) 不忽略行 |
| COUNT(DISTINCT user_id) | 去重计数 |
| AVG(score), MAX(score), MIN(score) | 均值、最大、最小 |
| GROUP BY city | 按城市分组,SELECT 只能有分组列或聚合 |
| GROUP BY city, channel | 多列联合分组 |
| HAVING COUNT(*) > 5 | 对分组后的结果过滤,不能用 WHERE |
| WHERE status = 1 GROUP BY city HAVING SUM(amount) > 0 | 先过滤行再分组,最后过滤组 |
| GROUP BY DATE(create_time) | MySQL 按天聚合 |
| GROUP BY DATE_TRUNC('day', create_time) | PostgreSQL 按天聚合 |
| GROUP BY city WITH ROLLUP | MySQL 追加小计与总计行 |
| GROUP_CONCAT(name ORDER BY id SEPARATOR ',') | MySQL 组内拼接字符串 |
| STRING_AGG(name, ',' ORDER BY id) | PostgreSQL 组内拼接 |
| FROM a INNER JOIN b ON a.id = b.aid | 只保留两边都匹配的行(JOIN 即内连接) |
| FROM a LEFT JOIN b ON a.id = b.aid | 左表全保留,右表无匹配补 NULL |
| FROM a RIGHT JOIN b ON a.id = b.aid | 右表全保留,通常改写为左连接 |
| FROM a FULL OUTER JOIN b ON a.id = b.aid | 两边都保留;MySQL 需 UNION 模拟 |
| FROM a CROSS JOIN b | 笛卡尔积,慎用 |
| LEFT JOIN b ON a.id = b.aid WHERE b.aid IS NULL | 反连接:找出 a 中没有匹配 b 的行 |
| WHERE a.status = 1 AND b.amount > 0 | 把右表条件写进 WHERE 会把左连接变成内连接 |
| LEFT JOIN b ON a.id = b.aid AND b.status = 1 | 右表条件应写在 ON 里 |
| FROM t a JOIN t b ON a.pid = b.id | 自连接,常用于层级表 |
| SELECT ... FROM a UNION SELECT ... FROM b | 合并结果并去重 |
| SELECT ... FROM a UNION ALL SELECT ... FROM b | 合并不去重,性能更好 |
| WHERE id IN (SELECT aid FROM b) | 子查询作为多值条件 |
| WHERE EXISTS (SELECT 1 FROM b WHERE b.aid = a.id) | 相关子查询,命中即返回,通常优于 IN |
| WHERE NOT EXISTS (SELECT 1 FROM b WHERE b.aid = a.id) | 不存在匹配(差集) |
| SELECT * FROM (SELECT ... ) t | 派生表必须有别名 |
| WHERE score > (SELECT AVG(score) FROM t) | 标量子查询,只允许返回一行一列 |
| WITH s AS (SELECT ... ) SELECT * FROM s | CTE(公用表表达式),可读且可复用 |
| WITH RECURSIVE t (id, pid, lvl) AS (...) | 递归 CTE,处理树形/层级数据 |
| CREATE TEMPORARY TABLE tmp AS SELECT ... | 临时表,会话结束自动清理 |
| INSERT INTO t (a, b) VALUES (1, 'x') | 指定列插入,列名务必写全 |
| INSERT INTO t (a, b) VALUES (1,'x'), (2,'y') | 批量插入,比循环单条快得多 |
| INSERT INTO t2 SELECT * FROM t1 WHERE ... | 从查询结果插入(复制数据) |
| INSERT IGNORE INTO t VALUES (...) | MySQL:冲突行跳过不报错 |
| ON DUPLICATE KEY UPDATE cnt = cnt + 1 | MySQL:主键/唯一冲突时改为更新 |
| ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name | PostgreSQL 的 upsert 写法 |
| REPLACE INTO t VALUES (...) | MySQL:冲突先删后插,会改自增 id |
| UPDATE t SET status = 1 WHERE id = 10 | 更新必须带 WHERE,否则全表 |
| UPDATE t SET cnt = cnt + 1 WHERE id = 10 | 自增,读取与写入在同一条语句内完成 |
| UPDATE a JOIN b ON a.id = b.aid SET a.x = b.y | MySQL 多表联动更新 |
| DELETE FROM t WHERE id = 10 | 按条件删除行 |
| DELETE FROM t | 删全部行但保留表结构,可回滚 |
| TRUNCATE TABLE t | 清空并重置信增,速度快但不可回滚 |
| SELECT * FROM t FOR UPDATE | 事务内加行级写锁,防并发扣减出错 |
| SELECT * FROM t LOCK IN SHARE MODE | 共享读锁(PG 用 FOR SHARE) |
| CREATE TABLE IF NOT EXISTS t (id BIGINT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(64) NOT NULL DEFAULT '') | 建表基础语法 |
| UNIQUE KEY uk_name (name) | 唯一索引,业务幂等常用 |
| KEY idx_status_time (status, create_time) | 联合索引,列顺序决定能否命中 |
| FOREIGN KEY (uid) REFERENCES u(id) | 外键约束,保证引用完整性 |
| ON DELETE CASCADE ON UPDATE CASCADE | 父行删除/更新时联动子行 |
| CHECK (amount >= 0) | 取值约束;MySQL 8.0.16+ 才真正生效 |
| ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 | MySQL 建表尾:事务引擎 + 完整 Unicode |
| COMMENT '订单主表' | 列或表注释,便于协作 |
| ALTER TABLE t ADD COLUMN note VARCHAR(255) NULL | 加列 |
| ALTER TABLE t MODIFY COLUMN name VARCHAR(128) NOT NULL | MySQL 改列类型 |
| ALTER TABLE t CHANGE name user_name VARCHAR(64) | MySQL 重命名列 |
| ALTER TABLE t RENAME TO t2 | 重命名表 |
| ALTER TABLE t DROP INDEX idx_x, DROP COLUMN y | 删索引与列 |
| CREATE INDEX CONCURRENTLY idx_x ON t (x) | PostgreSQL 不锁表建索引 |
| DROP TABLE IF EXISTS t | 删表;先备份或用改名代替 |
| TRUNCATE TABLE t RESTART IDENTITY | PostgreSQL 清空并重置序列 |
| SHOW CREATE TABLE t | MySQL 查看建表语句 |
| DESC t | 查看列结构(PG 用 \d t) |
| ROW_NUMBER() OVER (PARTITION BY uid ORDER BY id DESC) | 组内编号,不并列 |
| RANK() OVER (...) | 并列跳号(1,1,3) |
| DENSE_RANK() OVER (...) | 并列不跳号(1,1,2) |
| SUM(amount) OVER (PARTITION BY uid ORDER BY day) | 累计求和(到当前行为止) |
| AVG(score) OVER (PARTITION BY cls) | 组内均值,行数不减少 |
| LAG(amount, 1, 0) OVER (ORDER BY day) | 取上一行,用于环比 |
| LEAD(amount, 1, 0) OVER (ORDER BY day) | 取下一行 |
| FIRST_VALUE(name) OVER (PARTITION BY uid ORDER BY id) | 组内第一行取值 |
| NTILE(4) OVER (ORDER BY score) | 分成 4 桶(分位数) |
| QUALIFY ROW_NUMBER() OVER (...) = 1 | PG/Snowflake 对窗口结果过滤,取每组最新一条 |
| IFNULL(x, 0) / COALESCE(a, b, 0) | 空值替换;COALESCE 跨库通用 |
| NULLIF(a, 0) | 相等时返回 NULL,常用于避免除零 |
| CONCAT(a, '-', b) | 字符串拼接;PG 也可用 a || b |
| SUBSTRING(name, 1, 3) / LEFT(name, 3) / RIGHT(name, 3) | 截取字符串 |
| LENGTH(name) / CHAR_LENGTH(name) | 字节长度与字符长度(中文不同) |
| UPPER(name) / LOWER(name) / TRIM(name) | 大小写与去空格 |
| REPLACE(name, 'a', 'b') | 替换片段 |
| LOCATE('key', name) | 子串位置,0 表示不存在 |
| ROUND(x, 2) / CEIL(x) / FLOOR(x) / ABS(x) | 数值取整与绝对值 |
| MOD(a, b) / a DIV b | 取余与整除 |
| NOW() / CURDATE() / CURTIME() | 当前日期时间 |
| DATE_ADD(NOW(), INTERVAL 7 DAY) | 日期加减(PG 用 NOW() + INTERVAL '7 days') |
| DATEDIFF(d1, d2) | 天数差;MySQL 参数顺序是结束在前 |
| DATE_FORMAT(t, '%Y-%m-%d %H:%i') | MySQL 日期转字符串 |
| STR_TO_DATE('2026-01-01', '%Y-%m-%d') | 字符串转日期 |
| EXTRACT(YEAR FROM t) / YEAR(t) / MONTH(t) | 取年、月等字段 |
| UNIX_TIMESTAMP(t) / FROM_UNIXTIME(sec) | 与秒级时间戳互转 |
| CAST(x AS DECIMAL(10, 2)) | 显式类型转换,跨库通用 |
| CASE WHEN s = 1 THEN '正常' ELSE '异常' END | 条件映射,可与聚合组合做行转列 |
| SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) AS ok_cnt | 条件计数(行转列常用技巧) |
| MD5(x) / SHA2(x, 256) | 哈希;密码请用专门算法而非 MD5 |
| UUID() / gen_random_uuid() | MySQL / PostgreSQL 生成 UUID |
| SHOW DATABASES / \l | 列出所有库(MySQL / PG) |
| USE db_name | MySQL 切换当前库 |
| SHOW TABLES LIKE 'order%' | 按名字模式找表 |
| SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'db' | 跨库查表清单 |
| SELECT COLUMN_NAME, DATA_TYPE FROM information_schema.COLUMNS WHERE TABLE_NAME = 't' | 查列定义 |
| SELECT ROUTINE_NAME FROM information_schema.ROUTINES | 查存储过程与函数 |
| CREATE USER 'app'@'%' IDENTIFIED BY '密码' | 新建账号 |
| GRANT SELECT, INSERT ON db.* TO 'app'@'%' | 按库授权,遵循最小权限 |
| REVOKE ALL ON db.* FROM 'app'@'%' | 回收权限 |
| SHOW GRANTS FOR 'app'@'%' | 查看已授权限 |
| mysqldump -u root -p db > backup.sql | MySQL 逻辑备份 |
| pg_dump -Fc db > backup.dump | PostgreSQL 自定义格式备份 |
| mysql -u root -p db < backup.sql | 导入备份 |
| LOAD DATA INFILE 'x.csv' INTO TABLE t FIELDS TERMINATED BY ',' | MySQL 快速导入 CSV |
| COPY t FROM 'x.csv' CSV HEADER | PostgreSQL 导入 CSV |