Skip to content

sql-select-query

SELECT 语句是 SQL(Structured Query Language,结构化查询语言)的基石。它用于从一个或多个数据库表中检索或查询数据。SELECT 查询的结果总是一个新的临时表,称为结果集 (result-set)。

最基本的 SELECT 语句有两个主要部分:SELECT 用于列出您想要的列,FROM 用于指定从中检索它们的表。

SELECT column1, column2, ..., columnN
FROM table_name;

对于所有示例,我们假设有一个 CUSTOMERS 表,其中包含以下数据:

CREATE TABLE CUSTOMERS(
ID INT PRIMARY KEY,
NAME VARCHAR(100) NOT NULL,
AGE INT NOT NULL,
ADDRESS VARCHAR(255),
SALARY DECIMAL(10, 2)
);
INSERT INTO CUSTOMERS VALUES
(1, 'Ramesh', 32, 'Ahmedabad', 2000.00),
(2, 'Khilan', 25, 'Delhi', 1500.00),
(3, 'Kaushik', 23, 'Kota', 2000.00),
(4, 'Chaitali', 25, 'Mumbai', 6500.00),
(5, 'Hardik', 27, 'Bhopal', 8500.00),
(6, 'Komal', 22, 'Hyderabad', 4500.00),
(7, 'Muffy', 24, 'Indore', 10000.00);

要仅检索每个客户的 ID、NAME 和 SALARY,您可以明确列出它们:

SELECT ID, NAME, SALARY
FROM CUSTOMERS;

此查询将产生以下结果集:

IDNAMESALARY
1Ramesh2000.00
2Khilan1500.00
3Kaushik2000.00
4Chaitali6500.00
5Hardik8500.00
6Komal4500.00
7Muffy10000.00

要从表中获取所有列,您可以使用星号 (*) 通配符。

SELECT * FROM CUSTOMERS;

最佳实践:虽然 SELECT * 对于交互式探索很有用,但您应该在应用程序代码中避免使用它。明确列出列使您的代码更具可读性、可预测性,并且更能抵御模式更改。它还可以通过只获取所需数据来减少网络流量。

SELECT 列表不限于现有列。您可以执行计算或操作数据,并使用 AS 关键字为结果列赋予新名称(别名)。

让我们为每个客户计算一个假设的 10% 年终奖金,并将新列命名为 AnnualBonus。

SELECT
NAME,
SALARY,
SALARY * 0.10 AS AnnualBonus
FROM CUSTOMERS;

示例:使用别名进行字符串拼接

Section titled “示例:使用别名进行字符串拼接”

您可以组合列。让我们创建一个名为 CustomerInfo 的列,它结合了客户的姓名和年龄。

-- 标准 SQL CONCAT 函数
SELECT
CONCAT(NAME, ' (Age: ', AGE, ')') AS CustomerInfo,
ADDRESS
FROM CUSTOMERS
ORDER BY NAME;

此查询产生清晰、描述性的输出:

CustomerInfoADDRESS
Chaitali (Age: 25)Mumbai
Hardik (Age: 27)Bhopal
Kaushik (Age: 23)Kota
Khilan (Age: 25)Delhi
Komal (Age: 22)Hyderabad
Muffy (Age: 24)Indore
Ramesh (Age: 32)Ahmedabad

一个完整的 SELECT 语句可以有许多子句。虽然您以特定的顺序编写它们,但数据库会以不同的逻辑顺序执行它们。理解这一点是掌握 SQL 的关键。

编写顺序:

SELECT ...
FROM ...
WHERE ...
GROUP BY ...
HAVING ...
ORDER BY ...
LIMIT ...;

逻辑处理顺序:

1. FROM: 获取源表。
2. WHERE: 过滤单个行。
3. GROUP BY: 将行聚合成组。
4. HAVING: 过滤聚合后的组。
5. SELECT: 选择最终的列/表达式。
6. ORDER BY: 对最终结果集进行排序。
7. LIMIT / FETCH: 限制返回的行数。
  • 格式化以提高可读性:将每个主要子句(SELECT、FROM、WHERE 等)放在新行上。缩进子查询和联接条件。这使得复杂查询更容易调试。
  • 使用有意义的别名:使用 AS 为计算列或联接中的表指定清晰的名称(例如,FROM CUSTOMERS AS c)。
  • 注释您的代码:使用 — 进行单行注释,使用 /* … */ 进行多行注释,以解释复杂逻辑的目的。
  • 使用 WHERE 尽早过滤:在 WHERE 子句中应用尽可能严格的过滤器。这减少了需要由后续阶段(如 GROUP BY 或 ORDER BY)处理的行数。
  • 考虑安全性:在应用程序中构建查询时,始终使用参数化查询(预处理语句)来防止 SQL 注入漏洞。切勿将用户输入直接拼接成查询字符串。