在数据驱动的时代,SQL(Structured Query Language)是与数据库沟通的基石语言,而查询语句则是其中最核心、最常用的部分,掌握如何编写SQL查询语句,意味着你拥有了从海量数据中精准提取所需信息的能力,本文将系统地介绍SQL查询语句的构成,从最基础的语法到更复杂的组合查询,帮助你构建清晰、高效的查询逻辑。

核心基础:SELECT与FROM
任何一条查询语句的起点都是SELECT和FROM,它们定义了“要什么”和“从哪里来”。
SELECT:用于指定你希望从数据库中检索的列,你可以使用来代表所有列,也可以明确列出列名,用逗号隔开。FROM:用于指定数据来源的表。
基本语法结构:
SELECT column1, column2, ... FROM table_name;
示例:
假设我们有一个名为employees的员工表,包含id, name, department, salary等列。
- 查询所有员工的所有信息:
SELECT * FROM employees;
- 只查询员工的姓名和薪资:
SELECT name, salary FROM employees;
精准筛选:WHERE子句
当数据量庞大时,我们通常不需要全部数据,而是需要满足特定条件的一部分。WHERE子句就扮演了“过滤器”的角色,它跟在FROM子句之后,用于设置筛选条件。
常用运算符:
| 运算符 | 描述 | 示例 |
|---|---|---|
| 等于 | WHERE department = '销售部' |
|
<> 或 |
不等于 | WHERE department <> '技术部' |
> |
大于 | WHERE salary > 8000 |
< |
小于 | WHERE salary < 5000 |
>= |
大于等于 | WHERE salary >= 8000 |
<= |
小于等于 | WHERE salary <= 5000 |
BETWEEN |
在某个范围内 | WHERE salary BETWEEN 6000 AND 9000 |
LIKE |
模糊匹配 | WHERE name LIKE '张%' (查找姓张的员工) |
IN |
在某个列表中 | WHERE department IN ('销售部', '市场部') |
示例:
查询销售部所有薪资大于7000的员工姓名和薪资。
SELECT name, salary FROM employees WHERE department = '销售部' AND salary > 7000;
逻辑组合:AND, OR, NOT
WHERE子句中的条件可以通过逻辑运算符进行组合,以实现更复杂的筛选逻辑。
AND:表示“且”,连接的所有条件必须同时满足。OR:表示“或”,连接的条件中至少有一个满足即可。NOT:表示“非”,用于取反,通常与其他运算符连用,如NOT IN、NOT LIKE。
示例:
查询技术部或市场部,且薪资不等于10000的员工。
SELECT * FROM employees WHERE (department = '技术部' OR department = '市场部') AND salary != 10000;
注意:当
AND和OR同时出现时,AND的优先级更高,为了代码清晰和避免逻辑错误,建议使用括号来明确运算顺序。
排序输出:ORDER BY子句
查询结果的默认顺序是未定义的,通常按照数据在表中的物理存储顺序返回。ORDER BY子句用于对结果集进行排序,它位于查询语句的末尾(在WHERE之后)。
ASC:升序排序,是默认选项。DESC:降序排序。
示例:
按薪资从高到低查询所有员工信息。

SELECT * FROM employees ORDER BY salary DESC;
也可以按多个列排序,例如先按部门升序,再按薪资降序。
SELECT * FROM employees ORDER BY department ASC, salary DESC;
限制数量:LIMIT与OFFSET
在分页显示或只需要查看前几条记录时,LIMIT子句非常有用。
LIMIT:指定返回的最大行数。OFFSET:指定在开始返回行之前要跳过的行数。
示例:
查询薪资最高的前3名员工。
SELECT * FROM employees ORDER BY salary DESC LIMIT 3;
实现分页查询,例如每页显示5条,获取第2页的数据(即跳过前5条,从第6条开始取)。
SELECT * FROM employees LIMIT 5 OFFSET 5;
分组聚合:GROUP BY与聚合函数
当需要对数据进行统计分析时,例如计算每个部门的平均薪资,就需要用到分组和聚合。
常用聚合函数:
COUNT():计数SUM():求和AVG():平均值MAX():最大值MIN():最小值
GROUP BY子句将具有相同值的行分组,然后聚合函数对每个组进行计算。
示例:
计算每个部门的员工人数和平均薪资。
SELECT department, COUNT(id) AS employee_count, AVG(salary) AS average_salary FROM employees GROUP BY department;
注意:在
SELECT列表中,任何非聚合列都必须出现在GROUP BY子句中。
筛选分组:HAVING子句
WHERE子句过滤的是行,而HAVING子句过滤的是GROUP BY创建的“组”,它通常与聚合函数一起使用,用于筛选满足特定条件的分组。
示例:
查询平均薪资大于8000的部门。

SELECT department, AVG(salary) AS average_salary FROM employees GROUP BY department HAVING AVG(salary) > 8000;
关联查询:JOIN
在实际应用中,数据通常被分散存储在多个表中以减少冗余。JOIN子句用于将这些表关联起来,基于它们之间的相关列,合并成一个结果集,最常用的是INNER JOIN(内连接)。
示例:
假设还有一个departments表,包含dept_id和dept_name,我们可以通过INNER JOIN将employees表和departments表连接起来,获取员工的姓名和其所在部门的完整名称。
SELECT e.name, d.dept_name FROM employees AS e INNER JOIN departments AS d ON e.department = d.dept_id;
这里使用了别名(
AS e,AS d)来简化表名的书写。
通过组合以上这些核心子句,你可以构建出功能强大且逻辑清晰的SQL查询语句,从简单的数据检索到复杂的统计分析,都能游刃有余,实践是掌握SQL的最佳途径,不断尝试和优化你的查询,你将能更高效地与数据对话。
相关问答FAQs
Q1: WHERE和HAVING有什么区别?我应该什么时候使用哪个?
A: WHERE和HAVING的主要区别在于它们作用的对象和执行顺序:
WHERE:在数据分组之前对表中的行进行筛选,它不能使用聚合函数(如COUNT(),SUM())。HAVING:在数据分组之后对组进行筛选,它通常与聚合函数一起使用,来过滤掉不满足条件的分组。
简单来说:先用WHERE过滤原始数据行,然后用GROUP BY对过滤后的行进行分组,最后用HAVING过滤这些分组,要找“平均薪资高于8000的部门”,必须先用GROUP BY按部门分组,再用HAVING来筛选这些分组。
Q2: INNER JOIN和LEFT JOIN有什么不同?
A: 它们的主要区别在于返回的结果集范围:
INNER JOIN(内连接):只返回两个表中连接字段(ON条件)相匹配的行,如果某行在其中一个表中没有匹配项,则该行不会出现在结果中,它关注的是“交集”。LEFT JOIN(左连接):返回左表的所有行,以及右表中与左表相匹配的行,如果左表的某行在右表中没有匹配项,结果中右表的部分将显示为NULL,它关注的是“左表全部”。
举个例子:如果employees表里有一个员工,但他在departments表中没有对应的部门记录,使用INNER JOIN时,这个员工不会出现在查询结果中,而使用LEFT JOIN时,这个员工仍然会出现在结果中,只是他的部门名称字段会是NULL。
【版权声明】:本站所有内容均来自网络,若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!