PostgreSQL SELECT 语句(手把手讲解)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观

在 PostgreSQL 数据库的世界中,SELECT 语句如同一把万能钥匙,能够打开数据检索的无限可能。无论是编程初学者还是中级开发者,掌握 SELECT 语句的精髓,都是高效操作数据库的基石。本文将通过 循序渐进 的方式,结合 实际案例形象比喻,深入浅出地讲解 PostgreSQL 中 SELECT 语句的核心用法。


一、SELECT 语句的基础语法

1.1 基本结构与功能

SELECT 语句是 SQL(Structured Query Language)中最常用的操作之一,其核心作用是从数据库中 检索数据。它的基本语法如下:

SELECT 列名1, 列名2, ...  
FROM 表名;  

例如,假设有一个名为 employees 的表,包含 id, name, department, salary 四个字段,执行以下语句:

SELECT name, salary FROM employees;  

这条语句会返回所有员工的姓名和薪资信息,类似于从图书馆的书架上 精准抽取指定书籍的标题和作者

1.2 通配符 * 的使用与注意事项

若希望一次性获取表中所有列的数据,可以使用通配符 *

SELECT * FROM employees;  

但需注意,频繁使用 SELECT * 可能导致性能问题,尤其是在表包含大量列或数据量较大时。因此,只选择需要的列 是优化查询效率的 关键原则

1.3 别名与计算列

通过 AS 关键字,可以为列或表设置临时名称(别名),提升可读性:

SELECT name AS 员工姓名, salary * 12 AS 年薪 FROM employees;  

此外,SELECT 还支持直接进行数学运算或字符串拼接,例如:

SELECT CONCAT('员工:', name, ', 部门:', department) AS 详细信息 FROM employees;  

二、数据过滤:WHERE 子句的精细化筛选

2.1 基础条件筛选

WHERE 子句允许根据特定条件过滤数据。例如,筛选薪资高于 10000 的员工:

SELECT name, salary  
FROM employees  
WHERE salary > 10000;  

这类似于在快递分拣中心,根据包裹重量筛选出需要特殊处理的包裹。

2.2 逻辑运算符与比较运算符

  • 逻辑运算符AND, OR, NOT 可组合多个条件。例如,筛选薪资在 8000 到 12000 之间的员工:
    SELECT * FROM employees  
    WHERE salary > 8000 AND salary < 12000;  
    
  • 比较运算符:除了 >, <, =,还可以使用 BETWEEN(区间判断)或 IN(枚举判断):
    SELECT * FROM employees  
    WHERE department IN ('技术部', '市场部');  
    

2.3 通配符与模糊查询

使用 LIKE 结合通配符 %_ 可进行模糊匹配:

  • % 表示任意字符序列:WHERE name LIKE '张%'(查找姓“张”的员工);
  • _ 表示单个字符:WHERE name LIKE '__阳'(查找姓名最后两位是“阳”的员工)。

三、排序与分页:让数据更有序

3.1 ORDER BY 子句的排序规则

通过 ORDER BY 可对查询结果进行排序,默认按升序(ASC),添加 DESC 表示降序:

SELECT name, salary  
FROM employees  
ORDER BY salary DESC;  

这如同将一叠纸条按薪资从高到低排列,方便快速定位最高薪或最低薪的员工。

3.2 LIMIT 和 OFFSET 实现分页

当数据量较大时,分页功能尤为重要:

SELECT * FROM employees  
ORDER BY id  
LIMIT 10 OFFSET 20;  

此语句表示:从第 21 条记录开始,取 10 条数据。这类似于翻阅书本时,直接跳到某一页并阅读固定数量的内容。


四、聚合函数与 GROUP BY:数据的统计与分组

4.1 聚合函数的典型应用场景

PostgreSQL 提供了多个聚合函数,用于统计数据:

  • COUNT():计算行数;
  • SUM():计算数值列的总和;
  • AVG():计算平均值;
  • MAX()/MIN():获取最大值或最小值。

例如,统计各部门的平均薪资:

SELECT department, AVG(salary) AS 平均薪资  
FROM employees  
GROUP BY department;  

这里 GROUP BY 将数据按 department 分组,再对每个组应用聚合函数。

4.2 HAVING 子句:分组后的条件过滤

HAVINGWHERE 类似,但专门用于过滤分组后的结果。例如,筛选平均薪资超过 15000 的部门:

SELECT department, AVG(salary)  
FROM employees  
GROUP BY department  
HAVING AVG(salary) > 15000;  

五、JOIN 操作:多表数据的关联查询

5.1 内联接(INNER JOIN)

当需要从多个表中获取相关数据时,JOIN 是核心工具。例如,employees 表与 departments 表通过 department_id 关联:

SELECT e.name, d.department_name, d.location  
FROM employees e  
INNER JOIN departments d  
ON e.department_id = d.id;  

这类似于快递分拣系统中,将包裹信息与收件人地址表关联,生成完整的物流信息。

5.2 外联接(LEFT/RIGHT JOIN)

若希望保留左表或右表的所有记录,即使关联条件不匹配,可用外联接:

SELECT e.name, d.department_name  
FROM employees e  
LEFT JOIN departments d  
ON e.department_id = d.id;  

此语句会返回所有员工的信息,即使某些员工的部门信息不存在(此时 department_nameNULL)。

5.3 跨库查询与复杂联接

PostgreSQL 还支持跨数据库的联接,或通过 USING 简化同名字段的联接:

SELECT *  
FROM employees e  
JOIN salaries s  
USING (id);  -- 假设两表均有同名的 id 字段  

六、子查询与 EXISTS:嵌套查询的威力

6.1 子查询的基本用法

子查询是将一个查询的结果嵌套在另一个查询中。例如,查找薪资高于公司平均薪资的员工:

SELECT name, salary  
FROM employees  
WHERE salary > (SELECT AVG(salary) FROM employees);  

子查询 (SELECT AVG(salary) ...) 的结果会被视为一个标量值,供外层查询使用。

6.2 EXISTS 子句:存在性判断

EXISTS 用于判断子查询是否有返回结果:

SELECT name  
FROM employees  
WHERE EXISTS (  
    SELECT 1  
    FROM projects  
    WHERE projects.employee_id = employees.id  
);  

此语句会列出所有参与过项目的员工。


七、性能优化:让 SELECT 语句更高效

7.1 索引的合理使用

为高频查询的字段(如 department_id, salary)创建索引,可显著提升查询速度:

CREATE INDEX idx_employee_salary ON employees(salary);  

但需注意,索引会占用存储空间,并可能降低写入性能。

7.2 避免 SELECT * 的陷阱

仅选择必要列,减少网络传输和内存消耗:

-- 不推荐  
SELECT * FROM employees WHERE department = '技术部';  
-- 推荐  
SELECT id, name, salary FROM employees WHERE department = '技术部';  

7.3 使用 EXPLAIN 分析查询计划

通过 EXPLAIN 可查看 PostgreSQL 如何执行查询:

EXPLAIN ANALYZE SELECT * FROM employees WHERE salary > 10000;  

此命令会输出查询的执行步骤、时间及资源消耗,帮助定位性能瓶颈。


八、进阶技巧:窗口函数与通用表表达式

8.1 窗口函数:按组计算而不分组

窗口函数允许在不使用 GROUP BY 的情况下,对数据进行分组计算。例如,为每个员工添加部门平均薪资:

SELECT  
    name,  
    salary,  
    AVG(salary) OVER (PARTITION BY department) AS 部门平均薪资  
FROM employees;  

此语句会为每一行计算所属部门的平均薪资,无需先分组再连接。

8.2 通用表表达式(CTE)

CTE 通过 WITH 子句创建临时结果集,简化复杂查询:

WITH 高薪员工 AS (  
    SELECT name, salary  
    FROM employees  
    WHERE salary > 20000  
)  
SELECT * FROM 高薪员工  
ORDER BY salary DESC;  

这类似于先整理出一个“高薪员工名单”,再基于该名单进行排序。


结论

PostgreSQL 的 SELECT 语句是数据库操作的核心工具,其功能远不止“简单查询”——通过灵活运用条件过滤、联接、聚合、子查询等技术,开发者可以完成从基础检索到复杂分析的多样化任务。无论是初学者通过基础语法入门,还是中级开发者通过窗口函数和性能优化提升技能,掌握 SELECT 语句的精髓,都能显著提升数据处理的效率与代码的优雅性。

实践建议:建议读者在本地 PostgreSQL 环境中创建示例表,逐步执行文中代码,并尝试修改条件或字段,观察结果变化。唯有亲手实践,才能真正理解 SELECT 语句的无限可能。

最新发布