psql是PostgreSQL数据库管理系统提供的交互式命令行工具,作为数据库管理员和开发人员日常操作的核心入口,其查询功能是数据检索、分析与管理的基础,掌握psql的查询列表,能够高效执行各种数据操作,优化查询效率,提升工作效率,本文将系统介绍psql中常用的数据库查询语句,涵盖基础语法、连接操作、分组聚合、子查询与窗口函数等,并通过示例和最佳实践帮助读者快速上手。

基础查询语句
基础查询语句是psql中最为常用的部分,用于从数据库表中检索数据,以下是核心命令及其功能说明:
| 命令 | 功能 | 示例 |
|---|---|---|
SELECT column1, column2 FROM table_name; | 检索指定列的数据 | SELECT name, email FROM users; |
WHERE condition | 根据条件过滤行 | SELECT * FROM orders WHERE status = 'completed'; |
LIMIT offset, count | 分页查询结果 | SELECT * FROM products LIMIT 10 OFFSET 20; |
DISTINCT | 去除重复行 | SELECT DISTINCT city FROM customers; |
SELECT基本用法:
SELECT语句用于指定要检索的列,表示所有列。SELECT id, name, age FROM employees;
此语句将返回employees表中id、name、age三列的所有数据。
WHERE条件过滤:
WHERE子句用于根据指定条件筛选行,支持比较运算符(=、<>、>、<、>=、<=)、逻辑运算符(AND、OR、NOT)和模式匹配(LIKE、ILIKE)。-- 查询年龄大于25岁的员工 SELECT * FROM employees WHERE age > 25; -- 查询名字以'A'开头的员工 SELECT * FROM employees WHERE name ILIKE 'A%';
分页查询LIMIT/OFFSET:
LIMIT用于限制返回的行数,OFFSET用于跳过指定数量的行,获取前10条数据:SELECT * FROM orders LIMIT 10;
跳过20条数据后取10条:
SELECT * FROM orders LIMIT 10 OFFSET 20;
去重DISTINCT:
DISTINCT关键字用于去除结果集中重复的行,统计不同城市客户数量:SELECT DISTINCT city FROM customers;
连接查询JOIN
连接查询用于合并两个或多个表中的数据,常见类型包括内连接、左连接、右连接和全连接。
| 连接类型 | 功能描述 | 示例 |
|---|---|---|
INNER JOIN | 匹配两个表中所有匹配的行 | SELECT users.name, orders.amount FROM users INNER JOIN orders ON users.id = orders.user_id; |
LEFT JOIN | 保留左表所有行,右表无匹配则NULL | SELECT users.name, orders.amount FROM users LEFT JOIN orders ON users.id = orders.user_id; |
RIGHT JOIN | 保留右表所有行,左表无匹配则NULL | SELECT users.name, orders.amount FROM users RIGHT JOIN orders ON users.id = orders.user_id; |
FULL JOIN | 保留所有行,无匹配则NULL | SELECT users.name, orders.amount FROM users FULL JOIN orders ON users.id = orders.user_id; |
内连接INNER JOIN:仅返回两个表中匹配的行,常用于关联数据。

-- 获取员工姓名和订单金额 SELECT employees.name, orders.amount FROM employees INNER JOIN orders ON employees.id = orders.employee_id;
左连接LEFT JOIN:保留左表(employees)的所有行,右表(orders)无匹配则显示NULL,适用于“所有员工及其订单信息”的场景。
SELECT employees.name, orders.amount FROM employees LEFT JOIN orders ON employees.id = orders.employee_id;
右连接RIGHT JOIN:与左连接相反,保留右表(orders)的所有行,左表无匹配则显示NULL。
SELECT employees.name, orders.amount FROM employees RIGHT JOIN orders ON employees.id = orders.employee_id;
全连接FULL JOIN:返回所有行,无论是否匹配,适用于需要包含所有数据的情况。
SELECT employees.name, orders.amount FROM employees FULL JOIN orders ON employees.id = orders.employee_id;
分组与聚合
分组与聚合操作用于对数据进行统计和分析,常与GROUP BY和聚合函数结合使用。
| 功能 | 命令 | 示例 |
|---|---|---|
| 分组 | GROUP BY column | SELECT department, COUNT(*) FROM employees GROUP BY department; |
| 计数 | COUNT(*) | SELECT COUNT(*) FROM orders; |
| 求和 | SUM(column) | SELECT SUM(amount) FROM orders; |
| 平均值 | AVG(column) | SELECT AVG(salary) FROM employees; |
| 最大值 | MAX(column) | SELECT MAX(price) FROM products; |
| 最小值 | MIN(column) | SELECT MIN(price) FROM products; |
| 过滤分组 | HAVING condition | SELECT department, COUNT(*) FROM employees GROUP BY department HAVING COUNT(*) > 10; |
GROUP BY分组:
GROUP BY子句用于将数据按指定列分组,通常与聚合函数结合使用,按部门统计员工数量:SELECT department, COUNT(*) AS employee_count FROM employees GROUP BY department;
聚合函数:常用的聚合函数包括
COUNT(计数)、SUM(求和)、AVG(平均值)、MAX(最大值)、MIN(最小值),这些函数用于对分组后的数据进行统计。- 计数:
COUNT(*)统计行数,COUNT(column)统计非NULL列数。-- 统计订单总数 SELECT COUNT(*) FROM orders; -- 统计有订单的员工数量 SELECT COUNT(DISTINCT employee_id) FROM orders;
- 求和:
SUM(column)计算列的和。-- 计算总订单金额 SELECT SUM(amount) FROM orders;
- 平均值:
AVG(column)计算列的平均值。-- 计算平均产品价格 SELECT AVG(price) FROM products;
- 最大值/最小值:
MAX(column)和MIN(column)分别获取列的最大值和最小值。-- 获取最高工资 SELECT MAX(salary) FROM employees; -- 获取最低产品价格 SELECT MIN(price) FROM products;
- 计数:
HAVING子句:
HAVING子句用于过滤分组后的结果,类似于WHERE,但HAVING作用于分组后的聚合结果,筛选员工数量超过10人的部门:SELECT department, COUNT(*) AS employee_count FROM employees GROUP BY department HAVING COUNT(*) > 10;
子查询与窗口函数
子查询和窗口函数是高级查询技巧,用于更复杂的数据检索和分析。
子查询:子查询是将一个查询嵌套在另一个查询中的结构,常用于条件过滤或作为结果集,子查询分为标量子查询、行子查询和表子查询。

- 标量子查询:返回单个值,用于条件比较。
-- 查询产品价格高于平均价格的记录 SELECT * FROM products WHERE price > (SELECT AVG(price) FROM products);
- 行子查询:返回一行数据,用于匹配多列。
-- 查询与某个员工部门相同的其他员工 SELECT * FROM employees WHERE department = (SELECT department FROM employees WHERE id = 1);
- 表子查询:返回一个表,用于JOIN或作为结果集。
-- 查询订单数量超过100的员工 SELECT employees.name, COUNT(orders.id) AS order_count FROM employees JOIN orders ON employees.id = orders.employee_id GROUP BY employees.name HAVING COUNT(orders.id) > 100;
- 标量子查询:返回单个值,用于条件比较。
窗口函数:窗口函数在查询结果集中对每一行计算一个值,常用于排名、行号、滞后/超前值等场景,窗口函数通过
OVER()子句定义窗口范围。- ROW_NUMBER():为每一行分配唯一行号,顺序由
ORDER BY指定。-- 获取工资排名前3的员工 SELECT name, salary, ROW_NUMBER() OVER (ORDER BY salary DESC) AS rank FROM employees ORDER BY salary DESC;
- RANK():为每一行分配排名,相同值会跳过排名,工资排名第二的员工,若第三名与第二名工资相同,则排名为3。
SELECT name, salary, RANK() OVER (ORDER BY salary DESC) AS rank FROM employees ORDER BY salary DESC;
- DENSE_RANK():为每一行分配排名,相同值不跳过排名,工资排名第二的员工,若第三名与第二名工资相同,则排名为2。
SELECT name, salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS rank FROM employees ORDER BY salary DESC;
- LAG():获取当前行之前某一行的值,常用于计算变化量。
-- 计算工资与前一年的变化量 SELECT name, salary, LAG(salary, 1) OVER (ORDER BY hire_date) AS prev_year_salary FROM employees ORDER BY hire_date;
- ROW_NUMBER():为每一行分配唯一行号,顺序由
性能优化建议
优化查询性能是提升数据库效率的关键,以下是一些常见优化方法:
| 优化方法 | 说明 | 示例 |
|---|---|---|
| 使用索引 | 为频繁查询的列创建索引,加速数据检索 | CREATE INDEX idx_users_name ON users (name); |
| 避免全表扫描 | 使用WHERE子句过滤数据,减少扫描范围 | SELECT * FROM orders WHERE user_id = 1;(而非SELECT * FROM orders;) |
| 优化JOIN顺序 | 先连接小表,再大表,减少关联数据量 | SELECT * FROM small_table JOIN large_table ON small_table.id = large_table.id; |
| 使用覆盖索引 | 索引包含查询所需的所有列,避免回表查询 | CREATE INDEX idx_orders_user_id ON orders (user_id);(若SELECT仅使用user_id) |
使用索引:索引是数据库中用于加速查询的数据结构,通过创建索引可以显著提高查询速度,为用户名创建索引:
CREATE INDEX idx_users_name ON users (name);
查询时,数据库会先使用索引快速定位符合条件的行,而非全表扫描。
避免全表扫描:全表扫描会遍历整个表的所有行,效率低下,使用
WHERE子句过滤数据,限制扫描范围,查询特定用户的订单:SELECT * FROM orders WHERE user_id = 1;
此查询会先通过索引快速定位
user_id = 1的行,而非扫描整个orders表。优化JOIN顺序:在多表JOIN查询中,先连接小表(数据量少),再连接大表(数据量大),可以减少关联的数据量。
-- 假设users表有1000行,orders表有10000行 SELECT users.name, orders.amount FROM users JOIN orders ON users.id = orders.user_id;
此查询会先扫描users表(1000行),再关联orders表(10000行),而非反过来。
常见问题解答(FAQs)
- 如何在psql中执行带参数的查询?
- 解答:psql支持两种方式传递参数:使用参数占位符(如
$1,$2)或使用变量(如@variable)。- 参数占位符:在查询中使用
$1,$2等占位符,执行时通过psql -c "SELECT * FROM users WHERE id = $1;" 1传递参数。SELECT
- 参数占位符:在查询中使用
- 解答:psql支持两种方式传递参数:使用参数占位符(如
图片来源于AI模型,如侵权请联系管理员。作者:酷小编,如若转载,请注明出处:https://www.kufanyun.com/ask/202402.html


