什么是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命名为e,departments命名为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内部的执行顺序和我们书写的顺序(SELECT → FROM → WHERE)略有不同,大致如下:
FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY
你注意到了吗?SELECT子句是在WHERE和GROUP 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子句(别名)。
- 列别名:在
SELECT子句的列名后书写AS "别名"。用于美化结果的显示,或为计算结果赋予清晰的名称。 - 表别名:在
FROM或JOIN子句的表名后书写AS 别名。在处理多表JOIN时能极大简化查询、提升可读性。 - 注意事项:在
SELECT子句中设置的列别名,不能在比它先执行的WHERE或GROUP BY子句中使用。
AS是每一位SQL使用者都应该掌握的必备关键字,无论你是刚入门的初学者,还是处理复杂数据的专家。从今天起,就给你的查询也起个“昵称”吧。未来的你和你的团队伙伴,一定会因此而感谢你的!