在数据驱动的时代,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
的主要区别在于它们作用的对象和执行顺序:
:在数据分组之前对表中的行进行筛选,它不能使用聚合函数(如 COUNT()
,SUM()
)。HAVING
:在数据分组之后对组进行筛选,它通常与聚合函数一起使用,来过滤掉不满足条件的分组。
简单来说:先用WHERE
过滤原始数据行,然后用GROUP BY
对过滤后的行进行分组,最后用HAVING
过滤这些分组,要找“平均薪资高于8000的部门”,必须先用GROUP BY
按部门分组,再用HAVING
来筛选这些分组。
Q2: INNER JOIN
和LEFT JOIN
有什么不同?
A: 它们的主要区别在于返回的结果集范围:
:只返回两个表中连接字段( ON
条件)相匹配的行,如果某行在其中一个表中没有匹配项,则该行不会出现在结果中,它关注的是“交集”。:返回左表的所有行,以及右表中与左表相匹配的行,如果左表的某行在右表中没有匹配项,结果中右表的部分将显示为 NULL
,它关注的是“左表全部”。
举个例子:如果employees
表里有一个员工,但他在departments
表中没有对应的部门记录,使用INNER JOIN
时,这个员工不会出现在查询结果中,而使用LEFT JOIN
时,这个员工仍然会出现在结果中,只是他的部门名称字段会是NULL
。
【版权声明】:本站所有内容均来自网络,若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!
发表回复