首页 / PostgreSQL 入门教程 / SELECT 基础与列/表别名

PostgreSQL 入门教程

SELECT 基础与列/表别名

本教程共 50 篇 · 第 22 篇 · 更新于 2026-07-31 · 约 8 分钟阅读

PostgreSQLPostgreSQL 入门教程SELECT别名AS表达式列

22. SELECT 基础与列/表别名

本节目标:学完你能用 SELECT 取出想要的列、给列和表达式起好懂的别名,也知道 SELECT * 的适用边界,还懂得 NULL 参与运算、以及列别名不能在 WHERE 里用的坑。

查询(SELECT)是平时用得最多的语句,作用是从表里「读」数据。它不改任何数据,只返回结果。

先放几条数据:

INSERT INTO users (username, email, age)
VALUES
  ('xiaoming', 'ming@example.com', 28),
  ('xiaohong', 'hong@example.com', 22),
  ('wangwu',   'wang@example.com', 35);

在 psql 里执行查询,提示符和结果长这样:

postgres=# SELECT username, age FROM users;
 username | age
----------+-----
 xiaoming |  28
 xiaohong |  22
 wangwu   |  35
(3 rows)

选指定的列

想看哪些列,就把列名写在 SELECT 后面,用逗号隔开:

SELECT username, age
FROM users;

只返回用户名和年龄两列。

取全部列(SELECT *)

* 是「所有列」的简写:

SELECT * FROM users;
Warning

SELECT * 写进应用程序代码里不是好习惯。表一加列,程序可能收到意料之外的字段;而且它永远把整行读出来,数据多时浪费带宽。临时在 psql 里瞅数据用 * 没问题,正式代码里建议把列名写全。

给列起别名(AS)

列名太长或不直观时,用 AS 起个临时的「别名」,只在这次查询里生效。

SELECT
  username AS 用户名,
  age AS 年龄
FROM users;

AS 可以省略,写成 username 用户名 也行,但我建议保留 AS,读起来更清楚。

表达式列

SELECT 后面不只能是列名,还可以是算出来的表达式。下面把年龄加 1 作为「明年年龄」:

SELECT
  username,
  age,
  age + 1 AS 明年年龄
FROM users;

字符串也能拼接。PostgreSQL 用 || 把字符串连起来:

SELECT
  username || ' 的邮箱是 ' || email AS 简介
FROM users;

如果不写别名,表达式列会显示成 ?column? 这种怪名字,所以建议都起个别名。

别名带空格要加引号

别名里含空格时,要用双引号包起来:

SELECT age + 1 AS "明年 年龄"
FROM users;
Note

这里用的是双引号 ",不是单引号。单引号在 SQL 里表示字符串,双引号才表示标识符(比如列名、别名)。

NULL 参与的运算

这一点很多人第一次遇到会懵:任何值和 NULL 做算术,结果还是 NULL。比如某行的 age 是 NULL,那 age + 1 也会是 NULL,不是 0,也不是 1。

SELECT
  username,
  age,
  age + 1 AS 明年年龄
FROM users;

如果某行 age 为空,它的「明年年龄」也会是空。记住:NULL 表示「未知」,和未知相加,结果依然是未知。

用常量和函数当列

SELECT 后面还能放常量或函数调用,结果会作为一列返回。比如加一列欢迎语,或算名字长度:

SELECT
  username,
  'hello' AS 问候,
  length(username) AS 名字长度
FROM users;

length() 返回字符串的字符数,常用来做长度校验或展示。

不查表也能 SELECT

SELECT 后面不一定非得跟 FROM。比如直接拿当前时间:

SELECT now();

这在测试函数、算个表达式时很方便,不需要任何表参与。

表别名

查询里还能给表起别名,写法也是 表名 AS 别名。单表查询时图省事用一下:

SELECT u.username, u.age
FROM users AS u;

表别名真正的用武之地是多表连接(JOIN)和自连接,那边表名要重复写很多次,起个短别名 uo 会清爽很多。这里先知道有这么回事,连接章节再细讲。

常见错误

  • 把列别名用在 WHERE 里:下面这样会报错,因为 WHERE 在 SELECT 之前执行,还没生成「名字」这个别名:
    -- 错误写法
    SELECT username AS 名字, age FROM users WHERE 名字 = 'xiaoming';
    正确写法是在 WHERE 里用原列名:WHERE username = 'xiaoming'
  • 别名重复:给两列起了同样的别名,结果集会分不清,建议别重名。
  • 生产代码用 SELECT *:表结构一变就出问题,字段名要写全。

表达式里的运算顺序

表达式列里也能用括号控制优先级,和数学里一样。下面两种写法结果不同:

SELECT
  username,
  age + 1 * 2  AS 写法一,
  (age + 1) * 2 AS 写法二
FROM users;

age + 1 * 2 先算乘法,等于 age + 2(age + 1) * 2 先加后乘。不确定顺序时,加括号最稳。

布尔结果也能当列

SELECT 后面可以放一个比较,结果是一列 true / false。比如判断用户是否「资深」(年龄大于 30):

SELECT
  username,
  age,
  age > 30 AS 是否资深
FROM users;

返回的「是否资深」列就是布尔值,常用来在结果里直接打标记,或给上层程序做判断。

Note

布尔列(true/false)也能起别名,建议起个好懂的中文名,比如上面的「是否资深」,读结果时一眼就明白。

用「表名.列名」限定

当查询涉及多张表、列名可能重名时,要用 表名.列名 把列说清楚:

SELECT users.username, orders.amount
FROM users, orders
WHERE users.id = orders.user_id;

这种「表名.列名」的写法在多表查询里几乎是必须的,能避免「列名有歧义」的报错。单表查询里不写也行,写了更严谨。

选择列的顺序随你定

SELECT 后面列的顺序,决定结果里列的先后,和表定义无关。下面把 age 放前面也完全合法:

SELECT age, username, email
FROM users;

想先看哪列就看哪列,顺序你定。

一次写多个表达式列

表达式列可以写好几个,互相独立。比如同时算「明年年龄」和「大概出生年」:

SELECT
  username,
  age + 1 AS 明年年龄,
  2026 - age AS 大概出生年
FROM users;

2026 - age 是个简单减法,结果作为新列返回。注意 age 为 NULL 时,这两列也都会是 NULL。

别名还能在排序里复用

起好别名后,后面的「排序」章节你会看到,可以直接按别名排序,比如 ORDER BY 明年年龄。这里先记住:别名是这次查询里的临时名字,排序、分组时常会再用到它。

表达式列里也能嵌套函数

表达式不限于加减和拼接,还能套函数。比如把用户名转大写、再算长度:

SELECT
  username,
  upper(username) AS 大写名,
  length(username) AS 名字长度
FROM users;

upper() 把字母转成大写(中文不受影响),length() 返回字符数。函数章节会系统讲,这里先知道:表达式列里什么都能往里塞。

小结

  • SELECT 列... FROM 表 取指定列;SELECT * 取全部列。
  • AS 给列、表达式、表起临时别名,提升可读性。
  • 表达式也能当列返回,记得起别名,否则列名叫 ?column?
  • 任何值和 NULL 运算结果仍是 NULL。
  • 带空格的别名用双引号包起来;列别名不能在 WHERE 里用;正式代码里优先写全列名,少用 *