Appearance
数据查询
在本章中,我们将学习如何使用 SQL 查询语句从 PostgreSQL 数据库中检索数据。作为数据库最基础也是最常用的操作,掌握查询技巧对于任何数据库应用至关重要。
查询表基础
SELECT 语句概述
要从表中检索数据,我们需要使用 SQL 的SELECT
语句。这是数据库操作中最常用的命令之一。一个完整的 SELECT 语句通常包含以下几个部分:
- 选择列表:指定要返回哪些列
- 表列表:指定要从哪些表中检索数据
- 条件限定:(可选)指定哪些行需要被检索
SELECT 语句是 SQL 中最复杂的语句之一,掌握它的基本用法是数据库学习的基础。随着经验的积累,你将能够构建更复杂的查询。
基本查询语法
sql
SELECT 列1, 列2, ... FROM 表名;
语法解释
SELECT
:关键字,表明这是一个查询操作列1, 列2, ...
:想要获取的列名称FROM
:关键字,指定数据来源表名
:要查询的表
查询所有列
假设我们有一个存储天气信息的表weather
,如果想检索表中的所有行和所有列,可以使用星号*
:
sql
SELECT * FROM weather;
运行上述查询,我们将获得如下结果:
city | temp_lo | temp_hi | prcp | date
---------------+---------+---------+------+------------
San Francisco | 46 | 50 | 0.25 | 1994-11-27
San Francisco | 43 | 57 | 0 | 1994-11-29
Hayward | 37 | 54 | | 1994-11-29
(3 rows)
这与下面这条明确列出所有列名的查询效果相同:
sql
SELECT city, temp_lo, temp_hi, prcp, date FROM weather;
虽然`SELECT *`在临时查询或探索数据时很方便,但在生产环境的代码中被认为是不好的编程风格。这是因为当表结构变化(如添加新列)时,查询结果也会随之变化,可能导致应用程序错误。
使用表达式和列别名
SELECT 语句不仅可以检索表中的原始列,还可以在查询中使用表达式计算新值:
sql
SELECT city,
(temp_hi + temp_lo)/2 AS temp_avg,
date
FROM weather;
上述查询使用了算术表达式(temp_hi + temp_lo)/2
计算平均温度,并使用AS
子句将结果列重命名为temp_avg
:
city | temp_avg | date
---------------+----------+------------
San Francisco | 48 | 1994-11-27
San Francisco | 50 | 1994-11-29
Hayward | 45 | 1994-11-29
(3 rows)
TIP
AS
关键字是可选的,但使用它可以让查询更清晰易读。列别名可以让输出结果更有意义,也便于后续处理。
使用 WHERE 子句过滤数据
在实际应用中,我们通常只需要特定条件的数据,而不是表中的所有记录。WHERE
子句可以帮助我们筛选出符合特定条件的行:
sql
SELECT * FROM weather
WHERE city = 'San Francisco' AND prcp > 0.0;
这个查询只会返回旧金山下雨天(降水量大于 0)的天气记录:
city | temp_lo | temp_hi | prcp | date
---------------+---------+---------+------+------------
San Francisco | 46 | 50 | 0.25 | 1994-11-27
(1 row)
WHERE 子句支持多种布尔运算符:
AND
:两个条件都必须为真OR
:至少一个条件为真NOT
:条件的否定
业务场景示例
假设你是一家连锁服装店的数据分析师,需要找出所有在寒冷天气(温度低于 40 度)且有降水的日子,以分析特殊天气对销售的影响:
sql
SELECT date, city, temp_lo, prcp
FROM weather
WHERE temp_lo < 40 AND prcp > 0;
对查询结果排序
为了让查询结果更有条理,我们可以使用ORDER BY
子句按照指定的列进行排序:
sql
SELECT * FROM weather
ORDER BY city;
结果将按城市名称的字母顺序排列:
city | temp_lo | temp_hi | prcp | date
---------------+---------+---------+------+------------
Hayward | 37 | 54 | | 1994-11-29
San Francisco | 43 | 57 | 0 | 1994-11-29
San Francisco | 46 | 50 | 0.25 | 1994-11-27
如果需要更精确的排序,可以指定多个排序列:
sql
SELECT * FROM weather
ORDER BY city, temp_lo;
这会先按城市名排序,对于相同城市的记录再按最低温度排序。
去除重复行
如果我们只关心不同的值而不需要重复项,可以使用DISTINCT
关键字:
sql
SELECT DISTINCT city FROM weather;
这将返回表中出现的不同城市名称,而不会重复:
city
---------------
Hayward
San Francisco
(2 rows)
为了确保结果的一致性,我们可以同时使用DISTINCT
和ORDER BY
:
sql
SELECT DISTINCT city
FROM weather
ORDER BY city;
在某些早期版本的 PostgreSQL 及其他数据库系统中,`DISTINCT`的实现会自动对行进行排序,但现代 PostgreSQL 不保证这一行为。如果排序很重要,请始终明确使用`ORDER BY`。
实际应用示例
sql
-- 查询所有城市的天气记录
SELECT * FROM weather;
sql
-- 查询特定城市的天气
SELECT * FROM weather
WHERE city = 'San Francisco';
sql
-- 计算华氏温度并重命名列
SELECT city,
date,
temp_lo AS celsius_low,
temp_hi AS celsius_high,
temp_lo * 9/5 + 32 AS fahrenheit_low,
temp_hi * 9/5 + 32 AS fahrenheit_high
FROM weather;
sql
-- 按日期降序排列,显示最新的天气记录
SELECT * FROM weather
ORDER BY date DESC;
查询最佳实践
实践 | 说明 | 示例 |
---|---|---|
避免使用SELECT * | 在生产代码中明确指定需要的列 | SELECT city, date, temp_hi FROM weather |
使用有意义的列别名 | 使结果更易理解 | SELECT temp_hi AS high_temperature |
限制返回的行数 | 对于大表查询时提高性能 | SELECT * FROM weather LIMIT 100 |
使用索引列作为过滤条件 | 提高查询性能 | WHERE date BETWEEN '1994-11-01' AND '1994-11-30' |
编写可读性强的查询 | 合理缩进和使用注释 | 参考本文中的 SQL 示例 |
虽然 PostgreSQL 支持复杂的 SQL 查询,但从掌握这些基础操作开始,将帮助你建立坚实的数据库技能基础。
总结
在本章中,我们学习了:
- 使用
SELECT
语句从表中检索数据 - 如何选择特定列或所有列
- 在查询中使用表达式和列别名
- 使用
WHERE
子句过滤数据 - 使用
ORDER BY
对结果排序 - 使用
DISTINCT
去除重复行