以下是 DQL(数据查询语言) 的详细技术说明,涵盖语法结构、核心子句及高级功能:
🔍 DQL 核心:SELECT
语句结构
SELECT [DISTINCT] 列1, 列2, 聚合函数(列)
FROM 表名
[JOIN 关联表 ON 条件]
[WHERE 过滤条件]
[GROUP BY 分组列]
[HAVING 分组后过滤]
[ORDER BY 排序列 [ASC|DESC]]
[LIMIT 行数]
[OFFSET 起始位置];
📌 1. 基础查询
操作 | 语法示例 | 说明 |
---|
查询所有列 | SELECT * FROM employees; | 返回表中全部字段 |
查询指定列 | SELECT name, salary FROM employees; | 投影特定字段 |
去重查询 | SELECT DISTINCT dept_id FROM employees; | 消除重复值 |
列别名 | SELECT name AS 姓名, salary*12 AS 年薪 FROM employees; | 结果集列重命名 |
⚙️ 2. 条件过滤 (WHERE
)
条件类型 | 运算符示例 | 说明 |
---|
比较运算 | salary > 10000 | > , < , >= , <= , = , <> |
逻辑运算 | age >= 25 AND salary < 20000 | AND , OR , NOT |
模糊匹配 | name LIKE '张%' | % (任意字符), _ (单字符) |
范围匹配 | id IN (101, 102, 105) | IN , BETWEEN 1000 AND 5000 |
空值判断 | email IS NULL | IS NULL , IS NOT NULL |
📊 3. 数据分组 (GROUP BY
)
操作 | 语法示例 | 说明 |
---|
单列分组 | SELECT dept_id, AVG(salary) FROM employees GROUP BY dept_id; | 按部门计算平均薪资 |
多列分组 | SELECT dept_id, job_role, COUNT(*) FROM employees GROUP BY dept_id, job_role; | 多维度统计 |
常用聚合函数 | COUNT() , SUM() , AVG() , MAX() , MIN() | 需配合 GROUP BY 使用 |
🎯 4. 分组后过滤 (HAVING
)
SELECT dept_id, AVG(salary)
FROM employees
GROUP BY dept_id
HAVING AVG(salary) > 8000;
⚠️ 与 WHERE
区别:
WHERE
在分组前过滤原始数据HAVING
在分组后过滤聚合结果
🔗 5. 表连接 (JOIN
)
连接类型 | 语法示例 | 结果说明 |
---|
内连接 | SELECT * FROM orders INNER JOIN customers ON orders.cust_id = customers.id; | 仅返回匹配成功的行 |
左外连接 | SELECT * FROM employees LEFT JOIN departments ON employees.dept_id = departments.id; | 左表全保留 + 右表匹配值 |
右外连接 | SELECT * FROM departments RIGHT JOIN employees ON departments.id = employees.dept_id; | 右表全保留 + 左表匹配值 |
全外连接 | SELECT * FROM tableA FULL OUTER JOIN tableB ON tableA.key = tableB.key; | 返回所有行(MySQL 通过 UNION 模拟) |
交叉连接 | SELECT * FROM colors CROSS JOIN sizes; | 笛卡尔积(所有组合) |
🔁 6. 子查询 (Subquery)
类型 | 语法示例 | 说明 |
---|
标量子查询 | SELECT name, (SELECT MAX(salary) FROM employees) AS max_sal FROM employees; | 返回单行单列值(可替代常量) |
行子查询 | SELECT * FROM orders WHERE (cust_id, amount) IN (SELECT cust_id, MAX(amount) FROM orders GROUP BY cust_id); | 返回单行多列 |
关联子查询 | SELECT name, salary FROM employees e1 WHERE salary > (SELECT AVG(salary) FROM employees e2 WHERE e2.dept_id = e1.dept_id); | 引用外部查询变量 |
EXISTS 子查询 | SELECT * FROM customers c WHERE EXISTS (SELECT 1 FROM orders o WHERE o.cust_id = c.id); | 检查是否存在相关记录 |
📈 7. 高级功能
排序 (ORDER BY
)
SELECT name, salary
FROM employees
ORDER BY salary DESC, name ASC;
分页 (LIMIT/OFFSET
)
SELECT * FROM products
ORDER BY price DESC
LIMIT 10 OFFSET 20;
窗口函数 (Window Functions)
SELECT name, department,salary,RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS dept_rank
FROM employees;
公共表表达式 (CTE)
WITH high_salary_emps AS (SELECT * FROM employees WHERE salary > 10000
)
SELECT dept_id, COUNT(*) FROM high_salary_emps GROUP BY dept_id;
🧩 8. 组合查询 (UNION
)
SELECT city FROM customers
UNION
SELECT city FROM suppliers;
SELECT city FROM customers
UNION ALL
SELECT city FROM suppliers;
⚠️ 关键注意事项
- 执行顺序:
- 别名使用:
SELECT
中定义的别名不能在 WHERE
中使用- 可在
ORDER BY
和 HAVING
中使用
- NULL 处理:
- 聚合函数忽略 NULL 值(
COUNT(列)
不计数 NULL) - 条件
WHERE col = NULL
无效 → 需用 IS NULL