PostgreSQL 别名

PostgreSQL 别名(Alias) 完全指南

别名是 SQL 的“命名魔法”,让查询 更简洁、可读、可复用
本文涵盖 列别名、表别名、CTE 别名、函数别名、表达式别名、JSON 别名、窗口函数别名、命名规范、性能影响、常见陷阱、最佳实践 等全部内容。


一、别名三大类型

类型语法作用
列别名column AS alias重命名输出列
表别名table AS alias简化表名,解决冲突
CTE 别名WITH cte_name AS (...)命名子查询

二、准备测试数据

CREATE TABLE employees (
    id BIGSERIAL PRIMARY KEY,
    full_name TEXT,
    email_address TEXT,
    dept_code VARCHAR(10),
    annual_salary NUMERIC(10,2),
    hire_date DATE,
    tags TEXT[]
);

INSERT INTO employees (full_name, email_address, dept_code, annual_salary, hire_date, tags) VALUES
('Alice Johnson', 'alice.j@company.com', 'IT', 85000, '2023-01-15', '{"dev","lead"}'),
('Bob Smith',     'bob.s@company.com',   'HR', 52000, '2022-06-10', '{"hr"}'),
('Carol White',   'carol.w@company.com', 'IT', 92000, '2024-03-20', '{"dev","ai"}'),
('Dave Brown',    NULL,                  'IT', 78000, '2021-11-05', '{"dev"}'),
('Eve Davis',     'eve.d@company.com',   'HR', 48000, '2023-12-01', '{"hr","recruit"}');

三、列别名(Column Alias)

1. 基本语法

SELECT 
    full_name AS name,
    annual_salary AS salary,
    hire_date AS "Hire Date"  -- 保留空格/大小写
FROM employees;

2. 表达式别名

SELECT 
    full_name,
    annual_salary / 12 AS monthly_salary,
    UPPER(full_name) AS "FULL NAME",
    COALESCE(email_address, 'N/A') AS email
FROM employees;

3. 聚合函数别名

SELECT 
    dept_code,
    COUNT(*) AS headcount,
    AVG(annual_salary) AS avg_salary,
    STRING_AGG(full_name, ', ') AS team_members
FROM employees
GROUP BY dept_code;

四、表别名(Table Alias)

1. 简化长表名

SELECT e.full_name, e.annual_salary
FROM employees AS e;
-- 等价于
FROM employees e;

2. 自连接(Self-Join)

-- 员工与经理
SELECT 
    e.full_name AS employee,
    m.full_name AS manager
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id;

3. 多表 JOIN 避免冲突

SELECT 
    e.full_name,
    d.name AS dept_name
FROM employees e
JOIN departments d ON e.dept_code = d.code;

五、CTE 别名(WITH 子句)

WITH 
it_employees AS (
    SELECT * FROM employees WHERE dept_code = 'IT'
),
high_earners AS (
    SELECT full_name, annual_salary
    FROM it_employees
    WHERE annual_salary > 80000
)
SELECT * FROM high_earners;

六、函数与窗口函数别名

SELECT 
    full_name,
    EXTRACT(YEAR FROM hire_date) AS hire_year,
    ROW_NUMBER() OVER (PARTITION BY dept_code ORDER BY annual_salary DESC) AS rank_in_dept
FROM employees;

七、JSON 与数组别名

SELECT 
    full_name,
    tags[1] AS primary_tag,
    config->>'level' AS "Employee Level"
FROM employees;

八、别名命名规范(推荐)

类型规范示例
表别名1-3 个字母,表名缩写e, emp, d, dept
列别名清晰、驼峰或下划线employee_name, deptName
CTE 别名动词 + 名词active_employees, monthly_sales
避免保留字、空格开头order, group
-- 推荐
SELECT e.full_name AS employee_name FROM employees e;

-- 不推荐
SELECT employees.full_name AS name FROM employees;  -- 太长

九、别名与 ORDER BY

1. 支持别名(推荐)

SELECT full_name, annual_salary AS salary
FROM employees
ORDER BY salary DESC;

2. 不支持列序号(不推荐)

ORDER BY 2  -- 模糊,易出错

十、性能影响:几乎为 0

项目影响
列别名无(仅输出层)
表别名无(优化器内部使用)
CTE 别名可能物化(MATERIALIZED
-- 性能相同
SELECT full_name AS name FROM employees;
SELECT full_name FROM employees;

十一、常见陷阱与解决方案

陷阱说明解决方案
AS 省略导致歧义SELECT col AS FROM table始终加 AS
别名与保留字冲突SELECT col AS order用双引号 "order"
GROUP BY 用别名不允许用原始列或列序号
WHERE 用别名不允许用原始表达式
-- 错误:WHERE 不能用别名
SELECT full_name, annual_salary AS salary
FROM employees
WHERE salary > 80000;  -- 语法错误!

-- 正确
SELECT full_name, annual_salary AS salary
FROM employees
WHERE annual_salary > 80000;
-- GROUP BY 别名错误
SELECT dept_code, COUNT(*) AS cnt
FROM employees
GROUP BY cnt;  -- 错误!

-- 正确
GROUP BY dept_code;
-- 或
GROUP BY 1;  -- 列序号

十二、最佳实践 Checklist

项目建议
表别名必加提升可读性
列别名清晰避免 col1, col2
AS 显式使用避免歧义
ORDER BY 用别名简洁
WHERE/GROUP BY 用原始列符合语法
CTE 别名动词化filtered_data, aggregated_sales
避免保留字"order", "group"

十三、一键生产级查询模板

WITH active_employees AS (
    SELECT 
        id,
        full_name AS employee_name,
        email_address AS email,
        dept_code,
        annual_salary AS salary,
        hire_date
    FROM employees
    WHERE hire_date >= '2023-01-01'
),
dept_stats AS (
    SELECT 
        dept_code,
        COUNT(*) AS headcount,
        AVG(salary) AS avg_salary,
        MAX(salary) AS max_salary
    FROM active_employees
    GROUP BY dept_code
)
SELECT 
    ae.employee_name,
    ae.email,
    ae.salary,
    ds.headcount,
    ds.avg_salary,
    RANK() OVER (PARTITION BY ae.dept_code ORDER BY ae.salary DESC) AS salary_rank
FROM active_employees ae
JOIN dept_stats ds ON ae.dept_code = ds.dept_code
ORDER BY ds.avg_salary DESC, ae.salary DESC;

十四、快速实战:5 分钟掌握别名

-- 1. 列别名
SELECT full_name AS name, annual_salary AS salary FROM employees;

-- 2. 表别名 + 自连接
SELECT e.full_name AS emp, m.full_name AS mgr 
FROM employees e 
LEFT JOIN employees m ON e.manager_id = m.id;

-- 3. CTE 别名
WITH it_team AS (SELECT * FROM employees WHERE dept_code = 'IT')
SELECT employee_name, salary FROM it_team;

-- 4. 窗口函数别名
SELECT 
    full_name,
    dept_code,
    ROW_NUMBER() OVER (PARTITION BY dept_code ORDER BY annual_salary DESC) AS rank
FROM employees;

-- 5. ORDER BY 别名
SELECT annual_salary * 12 AS yearly 
FROM employees 
ORDER BY yearly DESC;

现在就动手
employees 表中:

  1. 查询 full_namename, annual_salarysalary
  2. 自连接查询员工与经理名(用 em 别名)
  3. 用 CTE 别名 high_earners 筛选 salary > 80000
  4. 计算月薪并用别名 monthly,按其降序
  5. RANK() 给每个部门薪资排名,用别名 dept_rank

十五、别名 vs 视图 vs 函数

方式别名视图函数
复用性仅当前查询
参数化NoNoYes
性能最高中等
适用临时命名固定查询复杂逻辑
-- 视图替代 CTE 别名
CREATE VIEW v_active_employees AS
SELECT id, full_name AS name, annual_salary AS salary
FROM employees WHERE hire_date >= '2023-01-01';

需要我生成:

  • 复杂报表 + 别名规范模板?回复 报表模板
  • 自动生成别名(Python)?回复 Python 别名
  • 别名与 EXPLAIN 性能分析?回复 EXPLAIN 分析
  • 别名命名规范检查工具?回复 命名检查

随时告诉我!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注