🇯🇵 日本語 | 🇺🇸 English | 🇪🇸 Español | 🇵🇹 Português | 🇹🇭 ไทย | 🇨🇳 中文

什么是SQL的AS子句?用别名给表和列起名,让查询变得更易读!

“计算结果的列名是 `price * 1.1` 这种,太难看了……”
“JOIN之后表名太长,查询语句乱七八糟的好难读!”

刚开始写SQL时,你是否也曾有过这种“小小的烦恼”?查询能跑通,但总觉得不好读。过段时间再回来看,自己都得花时间才能看懂当初写的是什么……

能瞬间解决这些烦恼的魔法关键字,就是我们这次要介绍的“AS”子句。使用AS,可以为表和列设置“别名(alias)”。这就像用昵称来称呼一个名字很长的人一样。只要熟练运用AS,SQL查询语句就能变得异常易读和易写!

本文将通过可直接复制粘贴运行的示例代码,为你彻底解说能极大提升SQL可读性的AS子句的基础用法,乃至与JOIN和自连接等相关的应用技巧。


准备:用于练习的表

首先,我们来准备一个表,体验一下别名的便利性。这次我们使用一个简单的商品表。


-- 如果表已存在则删除
DROP TABLE IF EXISTS products;

-- 创建商品表
CREATE TABLE products (
    id INT PRIMARY KEY,
    product_name VARCHAR(100),
    price INT,
    category VARCHAR(50)
);

-- 插入数据
INSERT INTO products (id, product_name, price, category) VALUES
(1, '高機能オフィスチェア', 35000, '家具'),
(2, '静音ワイヤレスキーボード', 8000, '周辺機器'),
(3, '4K対応27インチモニター', 42000, '周辺機器'),
(4, '電動昇降式デスク', 65000, '家具'),
(5, 'ノイズキャンセリングヘッドホン', 28000, 'オーディオ');
    

我们就用这张表,来看看AS子句的各种用法吧!


1. 列别名:美化结果的显示

列别名的功能是,将查询执行结果的列名(表头)改成一个易于理解的名字。它不会改变原表的列名,请放心使用。这个功能主要在输出报告或在应用程序中显示数据时非常有用。

示例1:将列名改为易于理解的中文名

当你不想直接显示像`product_name`或`price`这样的英文列名,而是希望显示为中文的“商品名”、“价格”时,这个功能就非常方便。


SELECT
    product_name AS "商品名",
    price AS "价格"
FROM
    products;
    

就像这样,只需在AS后面指定一个新的名字,结果的表头就变了。这样一来,即使是不懂SQL的人也能看懂报告了。


示例2:为计算结果的列命名

为计算或函数产生的结果列赋予一个清晰的名字,是AS最常见的用途之一。例如,我们来计算一下含税价格(价格 × 1.1)。


-- 如果没有AS,列名就会是计算表达式本身
SELECT
    product_name,
    price * 1.1
FROM
    products;
    

这样的话,列名就成了`price * 1.1`,很难看对吧?这时候就该AS出场了。


-- 使用AS来起一个易懂的名字
SELECT
    product_name AS "商品名",
    price * 1.1 AS "含税价格"
FROM
    products;
    

怎么样?仅仅是加上`AS "含税价格"`,结果就变得清晰多了。在使用聚合函数(如`COUNT`, `SUM`, `AVG`等)时,用AS来命名也是基本操作。

※ 顺便一提,在很多SQL环境中,只有列别名可以省略AS关键字(例如:`price "价格"`)。但是,为了提高代码的可读性,我们推荐明确地写出AS


2. 表别名:简化复杂的查询

表别名的功能是在查询内部为表赋予一个“临时的短名称”。这在需要`JOIN`多个表时能发挥出巨大作用。它能让查询语句变得更短、更简洁,并且能让人一目了然地知道正在引用哪个表的哪个列。

示例1:让JOIN语句更清晰

这里我们用“员工(employees)”和“部门(departments)”表来看看。


-- 为此示例准备表
DROP TABLE IF EXISTS employees;
DROP TABLE IF EXISTS departments;
CREATE TABLE departments (id INT, department_name STRING);
INSERT INTO departments VALUES (1, '営業部'), (2, '開発部');
CREATE TABLE employees (id INT, name STRING, department_id INT);
INSERT INTO employees VALUES (1, '山田 太郎', 1), (2, '鈴木 花子', 2);
    

不使用别名的话,每次都需要以`表名.列名`的形式来指定列属于哪个表,非常冗长。


-- 无别名(冗长的例子)
SELECT
    employees.name,
    departments.department_name
FROM
    employees
INNER JOIN
    departments ON employees.department_id = departments.id;
    

我们用表别名来重写一下。我们把employees命名为edepartments命名为d


-- 有别名(推荐的写法)
SELECT
    e.name,
    d.department_name
FROM
    employees AS e
INNER JOIN
    departments AS d ON e.department_id = d.id;
    

是不是清爽多了!只用e.name就能明确表示“employees表的name列”,整个查询的可读性也大大提高了。


实践!在浏览器中试试别名吧

久等了!这里是一个能让你亲手实践所学别名用法的环境。

请把下面的代码完整地复制下来,保存成一个如alias_practice.html这样的文件,然后在浏览器中打开它。试试给`INNER JOIN`查询加上别名,亲身体验一下查询语句的可读性能提高多少吧!


<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>SQL别名练习场</title>
    <script src="https://cdn.jsdelivr.net/npm/alasql@4"></script>
    <style>
        body { font-family: sans-serif; padding: 2rem; background-color: #f9f9f9; }
        .container { max-width: 800px; margin: auto; background: white; padding: 2rem; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); }
        h1 { color: #333; }
        textarea { width: 100%; height: 180px; font-family: monospace; font-size: 16px; padding: 10px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; margin-bottom: 1rem; }
        button { background-color: #007bff; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; }
        button:hover { background-color: #0056b3; }
        #result-area { margin-top: 2rem; }
        table { width: 100%; border-collapse: collapse; margin-top: 1rem; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
        .error { color: red; font-weight: bold; }
    </style>
</head>
<body>
    <div class="container">
        <h1>来试试别名吧!</h1>
        <p>在下方的文本框中输入SQL语句,然后点击“执行SQL”按钮。</p>
        <textarea id="sql-input">-- 在这里写下你的SQL
SELECT
    e.name AS "员工姓名",
    d.department_name AS "部门名称"
FROM
    employees AS e
INNER JOIN
    departments AS d ON e.department_id = d.id;</textarea>
        <button onclick="executeSQL()">执行SQL</button>
        <div id="result-area"></div>
    </div>

    <script>
        // 初始化数据库并为JOIN准备数据
        const db = new alasql.Database();
        db.exec(`
            CREATE TABLE departments (id INT, department_name STRING);
            INSERT INTO departments VALUES (1, '営業部'), (2, '開発部');
            CREATE TABLE employees (id INT, name STRING, department_id INT);
            INSERT INTO employees VALUES (1, '山田 太郎', 1), (2, '鈴木 花子', 2);
        `);

        function executeSQL() {
            const sql = document.getElementById('sql-input').value;
            const resultArea = document.getElementById('result-area');
            resultArea.innerHTML = '';

            try {
                const result = db.exec(sql);
                if (result.length > 0) {
                    resultArea.appendChild(createTable(result));
                } else {
                    resultArea.innerHTML = '<p>查询结果为0条。</p>';
                }
            } catch (e) {
                resultArea.innerHTML = `<p class="error">错误: ${e.message}</p>`;
            }
        }

        function createTable(data) {
            const table = document.createElement('table');
            const thead = table.createTHead();
            const tbody = table.createTBody();
            const headerRow = thead.insertRow();
            for (const key in data[0]) {
                const th = document.createElement('th');
                th.textContent = key;
                headerRow.appendChild(th);
            }
            data.forEach(rowData => {
                const row = tbody.insertRow();
                for (const key in rowData) {
                    const cell = row.insertCell();
                    cell.textContent = rowData[key];
                }
            });
            return table;
        }

        // 初始显示
        executeSQL();
    </script>
</body>
</html>
    

注意事项:别名的作用域和顺序

别名虽然非常方便,但有一个重要的规则需要遵守。这与“SQL的执行顺序”有关。

在`WHERE`或`GROUP BY`子句中不能使用列别名

SQL内部的执行顺序和我们书写的顺序(SELECTFROMWHERE)略有不同,大致如下:

FROMWHEREGROUP BYHAVINGSELECTORDER BY

你注意到了吗?SELECT子句是在WHEREGROUP BY子句之后才被处理的。因此,在SELECT子句中定义的列别名,是不能在比它先执行的WHERE子句等地方使用的。


-- 这个例子会报错
-- 使用 products 表进行说明
SELECT
    product_name AS "商品名"
FROM
    products
WHERE
    "商品名" = '高機能オフィスチェア';
    

上面的查询会报错。因为在执行WHERE子句的时候,“商品名”这个别名还不存在。这种情况下,必须使用原始的列名。(要测试这个错误,需要将上面实践区的数据准备改回 'products' 表)。


-- 这才是正确的写法
SELECT
    product_name AS "商品名"
FROM
    products
WHERE
    product_name = '高機能オフィスチェア';
    

另一方面,在SELECT子句之后处理的ORDER BY子句中,是可以使用列别名的。这一点非常方便,值得记住。


总结

辛苦了!这次我们解说了能极大提升SQL查询可读性和易写性的AS子句(别名)。

AS是每一位SQL使用者都应该掌握的必备关键字,无论你是刚入门的初学者,还是处理复杂数据的专家。从今天起,就给你的查询也起个“昵称”吧。未来的你和你的团队伙伴,一定会因此而感谢你的!