以下按场景分类整理标准 SQL 常用语法,兼容 MySQL、PostgreSQL、SQL Server 等主流数据库,差异处会单独标注。
一、基础查询与常用函数
1. 基础查询结构
SELECT [DISTINCT] 列名1, 列名2, 表达式
FROM 表名
WHERE 条件
GROUP BY 分组列
HAVING 分组后条件
ORDER BY 排序列 [ASC|DESC]
LIMIT 数量; -- MySQL/PostgreSQL;SQL Server用TOP,Oracle用ROWNUM
2. 常用单行函数
字符串函数
-- 字符串拼接
SELECT CONCAT(name, '-', age) FROM user;
-- 字符串长度
SELECT LENGTH(name), CHAR_LENGTH(name) FROM user;
-- 截取子串(位置从1开始)
SELECT SUBSTRING(name, 1, 3) FROM user;
-- 大小写转换
SELECT UPPER(name), LOWER(name) FROM user;
-- 去除空格
SELECT TRIM(name) FROM user;
-- 替换
SELECT REPLACE(name, 'a', 'b') FROM user;
数值函数
SELECT
ROUND(price, 2), -- 四舍五入保留2位小数
CEIL(price), -- 向上取整
FLOOR(price), -- 向下取整
ABS(price), -- 绝对值
MOD(id, 2) -- 取余
FROM goods;
日期函数
SELECT
NOW(), -- 当前日期时间
CURDATE(), -- 当前日期
YEAR(create_time), -- 提取年份
MONTH(create_time), -- 提取月份
DAY(create_time), -- 提取日
DATE_ADD(create_time, INTERVAL 7 DAY), -- 加7天
DATEDIFF(NOW(), create_time) -- 日期差(天)
FROM order_table;
聚合函数
SELECT
COUNT(*), -- 总行数
COUNT(score), -- 非空值行数
SUM(amount), -- 求和
AVG(score), -- 平均值
MAX(score), -- 最大值
MIN(score) -- 最小值
FROM student_score;
条件函数
-- IF 函数(MySQL)
SELECT IF(score >= 60, '及格', '不及格') FROM student;
-- CASE WHEN 通用语法
SELECT
CASE
WHEN score >= 90 THEN '优秀'
WHEN score >= 60 THEN '及格'
ELSE '不及格'
END AS level
FROM student;
二、多表连接查询
1. 内连接(INNER JOIN)
只返回两表匹配的行
SELECT u.name, o.order_no
FROM user u
INNER JOIN order_table o ON u.id = o.user_id;
2. 左连接(LEFT JOIN)
返回左表全部行,右表无匹配则为 NULL
SELECT u.name, o.order_no
FROM user u
LEFT JOIN order_table o ON u.id = o.user_id;
3. 右连接(RIGHT JOIN)
返回右表全部行,左表无匹配则为 NULL
SELECT u.name, o.order_no
FROM user u
RIGHT JOIN order_table o ON u.id = o.user_id;
4. 全连接(FULL JOIN)
返回两表所有行,无匹配处为 NULL(MySQL 不支持,可用 UNION 模拟)
-- PostgreSQL / SQL Server
SELECT u.name, o.order_no
FROM user u
FULL JOIN order_table o ON u.id = o.user_id;
5. 交叉连接(CROSS JOIN)
返回笛卡尔积
SELECT * FROM a CROSS JOIN b;
6. 自连接
表与自身连接
-- 查询员工及其上级姓名
SELECT e.name AS emp, m.name AS manager
FROM employee e
LEFT JOIN employee m ON e.manager_id = m.id;
7. 多表连接示例
SELECT u.name, o.order_no, p.product_name
FROM user u
JOIN order_table o ON u.id = o.user_id
JOIN order_detail d ON o.id = d.order_id
JOIN product p ON d.product_id = p.id;
三、子查询
1. WHERE 子句中的子查询
-- 查询成绩高于平均分的学生
SELECT name, score
FROM student
WHERE score > (SELECT AVG(score) FROM student);
-- IN 子查询
SELECT name
FROM student
WHERE class_id IN (SELECT id FROM class WHERE grade = 3);
-- EXISTS 子查询(存在即返回)
SELECT name
FROM user u
WHERE EXISTS (SELECT 1 FROM order_table o WHERE o.user_id = u.id);
2. FROM 子句中的子查询(派生表)
SELECT temp.avg_score
FROM (
SELECT class_id, AVG(score) AS avg_score
FROM student
GROUP BY class_id
) temp
WHERE temp.avg_score > 80;
3. SELECT 子句中的子查询(标量子查询)
SELECT
name,
(SELECT COUNT(*) FROM order_table o WHERE o.user_id = u.id) AS order_count
FROM user u;
四、集合运算
1. UNION / UNION ALL
- UNION:合并结果集并去重
- UNION ALL:合并结果集不去重(性能更高)
-- 要求:列数、数据类型对应一致
SELECT name, age FROM table_a
UNION
SELECT name, age FROM table_b;
SELECT name, age FROM table_a
UNION ALL
SELECT name, age FROM table_b;
2. 交集(INTERSECT)
返回两个结果集的共同部分(MySQL 不支持,可用 JOIN 模拟)
-- PostgreSQL / SQL Server
SELECT name FROM table_a
INTERSECT
SELECT name FROM table_b;
-- MySQL 替代写法
SELECT DISTINCT a.name
FROM table_a a
INNER JOIN table_b b ON a.name = b.name;
3. 差集(EXCEPT / MINUS)
返回第一个结果集有、第二个没有的行(MySQL 不支持)
-- PostgreSQL / SQL Server
SELECT name FROM table_a
EXCEPT
SELECT name FROM table_b;
-- Oracle 用 MINUS
SELECT name FROM table_a
MINUS
SELECT name FROM table_b;
-- MySQL 替代写法
SELECT a.name
FROM table_a a
LEFT JOIN table_b b ON a.name = b.name
WHERE b.name IS NULL;
五、公用表表达式(WITH)
1. 基础 CTE
WITH class_avg AS (
SELECT class_id, AVG(score) AS avg_score
FROM student
GROUP BY class_id
)
SELECT * FROM class_avg WHERE avg_score > 80;
2. 多个 CTE
WITH
t1 AS (SELECT * FROM user WHERE status = 1),
t2 AS (SELECT user_id, COUNT(*) cnt FROM order_table GROUP BY user_id)
SELECT t1.name, t2.cnt
FROM t1 LEFT JOIN t2 ON t1.id = t2.user_id;
3. 递归 CTE
适用于树形/层级结构(部门、分类等)
WITH RECURSIVE dept_tree AS (
-- 锚点成员:根节点
SELECT id, name, parent_id, 1 AS level
FROM department
WHERE parent_id IS NULL
UNION ALL
-- 递归成员
SELECT d.id, d.name, d.parent_id, dt.level + 1
FROM department d
INNER JOIN dept_tree dt ON d.parent_id = dt.id
)
SELECT * FROM dept_tree;
六、窗口函数(进阶常用)
SELECT
name,
class_id,
score,
-- 排名(并列跳号)
RANK() OVER (PARTITION BY class_id ORDER BY score DESC) AS rk,
-- 密集排名(并列不跳号)
DENSE_RANK() OVER (PARTITION BY class_id ORDER BY score DESC) AS drk,
-- 行号
ROW_NUMBER() OVER (PARTITION BY class_id ORDER BY score DESC) AS rn,
-- 班级平均分
AVG(score) OVER (PARTITION BY class_id) AS class_avg,
-- 累计求和
SUM(score) OVER (ORDER BY id) AS cum_sum
FROM student;
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/logen_s/article/details/169931717




