PostgreSQL 教程

SQL 基础语法与运算符

SQL 语法为编写与关系型数据库交互的查询提供了结构。掌握这种语法是高效检索、操作和管理数据的基础。了解运算符可以让你在 SQL 查询中指定条件、执行计算以及比较值。本章将介绍基础的 SQL 语法,引入不同类型的运算符,并演示如何在查询中有效地使用它们。

1. 基础 SQL 语法

SQL 语法建立在一系列关键字和规则之上,这些规则决定了如何构成有效的 SQL 语句。SQL 语句即是对数据库系统发出的指令。虽然 SQL 由 ANSI(美国国家标准协会)进行了标准化,但不同的数据库系统(包括 PostgreSQL)可能会有细微的差异。

1.1 SQL 核心组件

为了更好地理解一条完整的 SQL 语句是如何构成的,可以参考以下核心组件:

  • 子句 (Clauses): 子句是 SQL 语句中执行特定操作的组件。常见的子句包括 SELECTFROMWHEREORDER BYGROUP BYHAVING。每个子句都有特定的用途,并按规定的顺序编写。
  • 语句 (Statements): 语句是 SQL 中的一条完整指令。典型的 SQL 语句包含一个(或多个)子句,并以分号 (;) 结尾。不过在许多 PostgreSQL 环境中,尤其是在执行单条查询时,分号通常是可选的。
  • 表达式 (Expressions): 表达式是值、运算符和函数的组合,数据库对其进行计算以生成一个值。表达式通常用在 SELECT 列表或 WHERE 子句中。
  • 谓词 (Predicates): 谓词是计算结果为真 (true)、假 (false) 或未知 (unknown) 的条件。它们主要用在 WHERE 子句中,以根据特定标准过滤数据。
  • 查询 (Queries): 查询是从数据库中请求数据的操作。它通常使用 SELECT 语句及其他子句来制定,以指定要检索哪些数据以及如何组织这些数据。

2. 基础 SELECT 语句

SELECT 语句是 SQL 中查询数据的基础。

语法:

SELECT column1, column2, ...
FROM table_name;

示例: 假设你有一个名为 employees 的表,其中包含 employee_idfirst_namelast_namesalary 等列。

SELECT employee_id, first_name, last_name
FROM employees;

此查询从 employees 表的所有行中检索 employee_idfirst_namelast_name

2.1 查询所有列

要从表中选择所有列,你可以使用星号 *

SELECT *
FROM employees;

这将检索 employees 表中每一行的所有列。这在即席查询(ad-hoc querying)和探索数据时非常有用,但在生产环境中,通常建议明确指定你需要的列,以提升性能和清晰度。

3. 使用别名 (Aliases)

别名可以为列或表提供临时名称,使查询更具可读性且易于理解。

3.1 列别名

SELECT first_name AS given_name, last_name AS surname
FROM employees;

在这个例子中,在结果集里 first_name 被设置了别名 given_name,而 last_name 被设置了别名 surname

3.2 表别名

表别名在处理连接(Joins)时特别有用(我们将在后续模块中详细介绍)。

SELECT e.first_name, d.department_name
FROM employees AS e
JOIN departments AS d ON e.department_id = d.department_id;

在这里,employees 表被设置了别名 edepartments 表被设置了别名 d。这简化了查询并使其更具可读性。

4. 大小写敏感性

SQL 关键字通常是不区分大小写的,但为了提高可读性,最好的做法是将它们大写。表名和列名是否区分大小写,取决于数据库的配置。在 PostgreSQL 中,未加引号的标识符会被折叠为小写。给标识符加上双引号(例如 "MyTable")会使其区分大小写。

SELECT FirstName FROM Employees; -- 语法有效,但不推荐此风格
SELECT firstname FROM employees; -- 语法有效,但不推荐此风格
SELECT firstname FROM Employees; -- 可能会报错,取决于表的定义
SELECT FIRST_NAME FROM EMPLOYEES; -- 推荐的代码风格

5. SQL 运算符

运算符是执行一个或多个表达式操作的符号或关键字。它们用于构建条件、执行计算和操作数据。

5.1 运算符类型

SQL 运算符可大致分为以下几类:

  • 比较运算符: 用于比较两个表达式。
  • 逻辑运算符: 用于组合或否定条件。
  • 算术运算符: 用于执行数学计算。
  • 字符串运算符: 用于操作字符串。
  • 按位运算符: 用于执行按位操作(在标准 SQL 中较少见,但在 PostgreSQL 中可用)。

6. 比较运算符

比较运算符用在 WHERE 子句中,以根据指定的条件过滤数据。

运算符描述示例
=等于WHERE salary = 50000
!= 或 <>不等于WHERE salary != 50000
>大于WHERE salary > 50000
<小于WHERE salary < 50000
>=大于或等于WHERE salary >= 50000
<=小于或等于WHERE salary <= 50000
BETWEEN在某个范围内(包含边界)WHERE salary BETWEEN 40000 AND 60000
LIKE模式匹配WHERE first_name LIKE 'A%'
IN匹配列表中的任意值WHERE department_id IN (1, 2, 3)
IS NULL检查空值 (null)WHERE email IS NULL
IS NOT NULL检查非空值WHERE email IS NOT NULL

示例应用:

等于:

SELECT first_name, salary
FROM employees
WHERE salary = 60000;

此查询检索薪资刚好为 60000 的所有员工的 first_namesalary

不等于:

SELECT first_name, salary
FROM employees
WHERE department_id <> 5;

此查询检索不属于 5 号部门的所有员工的 first_namesalary

大于:

SELECT first_name, salary
FROM employees
WHERE salary > 75000;

此查询检索薪资大于 75000 的所有员工的 first_namesalary

小于或等于:

SELECT first_name, hire_date
FROM employees
WHERE hire_date <= '2020-01-01';

此查询检索在 2020 年 1 月 1 日或之前入职的所有员工的 first_namehire_date

BETWEEN (介于两者之间):

SELECT first_name, salary
FROM employees
WHERE salary BETWEEN 50000 AND 70000;

此查询检索薪资在 50000 到 70000 之间(含两端)的所有员工的 first_namesalary

LIKE (模糊匹配):LIKE 运算符用于模式匹配。% 代表零个或多个字符,_ 代表单个字符。

SELECT first_name
FROM employees
WHERE first_name LIKE 'J%';

此查询检索名字以 'J' 开头的所有员工的 first_name

SELECT first_name
FROM employees
WHERE last_name LIKE '_ohn%';

此查询检索姓氏的第二个、第三个和第四个字符为 'ohn' 的所有员工的 first_name

IN (包含于):

SELECT first_name, department_id
FROM employees
WHERE department_id IN (1, 3, 5);

此查询检索属于 1 号、3 号或 5 号部门的所有员工的 first_namedepartment_id

IS NULL / IS NOT NULL (空 / 非空):

SELECT first_name, email
FROM employees
WHERE email IS NULL;

此查询检索没有记录电子邮件地址 (NULL) 的所有员工的 first_nameemail

SELECT first_name, email
FROM employees
WHERE email IS NOT NULL;

此查询检索记录了电子邮件地址 (NOT NULL) 的所有员工的 first_nameemail

7. 逻辑运算符

逻辑运算符用于在 WHERE 子句中组合或否定条件。

运算符描述示例
AND逻辑与(且)WHERE salary > 50000 AND department_id = 1
OR逻辑或(或)WHERE department_id = 1 OR department_id = 2
NOT逻辑非(非)WHERE NOT department_id = 3 (等同于 WHERE department_id != 3)

示例应用:

AND (与):

SELECT first_name, salary, department_id
FROM employees
WHERE salary > 50000 AND department_id = 1;

检索薪资大于 50000 属于 1 号部门的所有员工。

OR (或):

SELECT first_name, salary, department_id
FROM employees
WHERE department_id = 1 OR department_id = 2;

检索属于 1 号部门 2 号部门的所有员工。

NOT (非):

SELECT first_name, department_id
FROM employees
WHERE NOT department_id = 3;

检索属于 3 号部门的所有员工。

组合 AND、OR 和 NOT:
组合多个逻辑运算符时,请使用括号 () 来明确计算顺序。

SELECT first_name, salary, department_id
FROM employees
WHERE (salary > 50000 AND department_id = 1) OR department_id = 2;

此查询检索满足以下条件的员工:(薪资大于 50000 属于 1 号部门)或者 属于 2 号部门。

8. 算术运算符

算术运算符对数值执行数学计算。

运算符描述示例
+加法SELECT salary + 1000 FROM employees
-减法SELECT salary - 1000 FROM employees
*乘法SELECT salary * 1.1 FROM employees
/除法SELECT salary / 12 FROM employees
%取模(求余)SELECT employee_id % 2 FROM employees

示例应用:

加法:

SELECT first_name, salary, salary + 1000 AS increased_salary
FROM employees;

此查询检索每位员工的信息,并计算 increased_salary(在当前薪资基础上加 1000)。

乘法:

SELECT first_name, salary, salary * 0.10 AS bonus
FROM employees;

此查询计算每位员工的奖金 bonus,等于当前薪资的 10%。

除法:

SELECT first_name, salary, salary / 12 AS monthly_salary
FROM employees;

此查询通过将年薪除以 12 来计算月薪 monthly_salary

9. 字符串运算符

字符串运算符用于操作字符串数据。PostgreSQL 提供了丰富的字符串函数和运算符。

运算符描述示例
LIKE模式匹配WHERE first_name LIKE 'A%'
NOT LIKE否定模式匹配WHERE first_name NOT LIKE 'A%'
||字符串拼接SELECT first_name || ' ' || last_name

示例应用:

拼接 (Concatenation):

SELECT first_name || ' ' || last_name AS full_name
FROM employees;

此查询将 first_namelast_name 列拼接在一起,中间加一个空格,从而生成 full_name(全名)。

LIKE:

SELECT first_name
FROM employees
WHERE first_name LIKE 'J%';

检索所有以字母 'J' 开头的 first_name

NOT LIKE:

SELECT first_name
FROM employees
WHERE first_name NOT LIKE 'J%';

检索所有以字母 'J' 开头的 first_name