# SELECT 基础

> 选择值与列，为查询结果命名，并查看系统目录。

---

LLMS 索引： [llms.txt](/llms.txt)

---

`SELECT` 是 SQL 的核心，用来读取数据。最简单的形式是没有 `FROM` 的 `SELECT expression`，它对表达式求值并返回一行。更常见的形式 `SELECT columns FROM table` 则对表中每个匹配的行返回一行结果。无论哪种形式，结果都是一个*关系*，由行和列组成，列名可以用 `AS` 修改。

## 本章要点 {#learn}

- 在 `SELECT` 中使用字面量与表达式（无需表）
- 用 `AS` 为结果列命名
- 在一次查询中选择多列
- 读取系统目录表
- 列别名与表别名的区别

## 示例 {#example}

```sql {num="3.1" caption="SELECT 基础"}
-- Literals and expressions: no FROM required
SELECT 1 AS one;
SELECT 2 + 3 AS sum, 10 / 4 AS quotient, 10 / 4.0 AS real_quotient;
SELECT 'hello' AS greeting, length('hello') AS chars;

-- Multiple columns in one row
SELECT 1 AS a, 2 AS b, 'x' AS c;

-- Reading from a table (here, a system catalog)
SELECT relname, relkind
FROM pg_class
WHERE relname = 'pg_database'
LIMIT 1;
```

每条 `SELECT` 都会产生一个结果集。`AS column_name` 为输出列重新命名；如果省略它，PostgreSQL 会为字面量生成 `?column?` 这样的名称，或沿用源列名。算术运算那一行值得再看一遍：`10 / 4` 返回整数 `2`，因为两个操作数都是整数；而 `10 / 4.0` 返回 `2.5`，因为其中一个操作数是 numeric 类型，不再使用整数除法。计算平均值和比率时，经常会遇到这个陷阱。

`pg_class` 是列出*关系*的系统目录，其中包括表、索引、视图、序列、物化视图等。`relkind` 列用于区分它们（`r` = 普通表，`i` = 索引，`v` = 视图，`m` = 物化视图，`S` = 序列）。查看系统目录是个值得养成的习惯，关于你所用模式的全部信息，都能在这里找到。

## 运行示例 {#run}

运行方式：

```text
$ psql -f source/select-basics.sql postgres
 one
-----
   1
(1 row)

 sum | quotient | real_quotient
-----+----------+---------------
   5 |        2 |            2.5
(1 row)

 greeting | chars
----------+-------
 hello    |     5
(1 row)

 a | b | c
---+---+---
 1 | 2 | x
(1 row)

   relname   | relkind
-------------+---------
 pg_database | r
(1 row)
```

## 常见陷阱 {#pitfalls}

- 忘记给表达式加 `AS`：`SELECT count(*)` 可以正常运行，但 `SELECT count(*) FROM ... WHERE total > 0 GROUP BY id` 如果没有 `AS order_count` 就会很难读懂。一定要为派生列设置别名。
- 整数除法：`1 / 2` 返回 `0`。对其中一侧做类型转换：`1::numeric / 2`，或写成 `1.0 / 2`。
- 双引号与单引号：`'hello'` 是字符串字面量，`"hello"` 是标识符（列名或表名）。混淆两者是 SQL 初学者最常犯的错误之一。

> [!TIP] 提示
> 各类列可以自由混用：`SELECT id, name, id * 2 AS doubled, current_timestamp AS fetched_at FROM fruits;` 完全合法。结果列按书写顺序排列，并使用别名作为名称；表达式的求值顺序则没有保证。

> [!NOTE] 动手练习
> 运行 `SELECT 10 * 2 AS twenty;`。然后尝试 `SELECT relname FROM pg_class WHERE relkind = 'r' LIMIT 5;`，查看数据库中的五个表名。在 `relname` 后加上 `, relkind`，观察结果。

## 下载 {#downloads}

SQL 文件： [select-basics.sql](/examples/source/select-basics.sql) · [全部示例文件](/examples/examples.zip) · [准备工作](/#prerequisites)
