PostgreSQL教程:SQL语法详解
PostgreSQL教程:SQL语法深度剖析
1. 引言
结构化查询语言(SQL)是关系数据库管理系统的核心。无论您使用的是哪种RDBMS,如PostgreSQL、MySQL、Oracle或SQL Server,SQL都是与之交互的基础语言。PostgreSQL以其对SQL标准的严格遵守、强大的功能和开源特性而闻名。本教程旨在深入探讨PostgreSQL中的SQL语法,提供全面的细节和实用示例,帮助开发人员和数据库管理员掌握这一关键技术。
2. 数据定义语言 (DDL)
DDL语句用于定义和修改数据库的结构。
2.1. CREATE TABLE
CREATE TABLE
语句用于创建新的数据表。
sql
CREATE TABLE products (
product_id SERIAL PRIMARY KEY,
product_name VARCHAR(255) NOT NULL,
price NUMERIC(10, 2),
category_id INTEGER REFERENCES categories(category_id),
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
SERIAL PRIMARY KEY
: 自动递增的整数,作为主键。VARCHAR(255)
: 可变长度字符串,最大长度为255个字符。NUMERIC(10, 2)
: 精确数值类型,总共10位数字,其中2位是小数。REFERENCES
: 外键约束,确保category_id
存在于categories
表中。DEFAULT CURRENT_TIMESTAMP
: 插入新行时自动设置当前时间戳。
2.2. 数据类型
PostgreSQL提供了丰富的数据类型:
- 数值类型:
SMALLINT
,INTEGER
,BIGINT
,NUMERIC
,REAL
,DOUBLE PRECISION
- 字符类型:
VARCHAR
,CHAR
,TEXT
- 日期/时间类型:
TIMESTAMP
,DATE
,TIME
,INTERVAL
- 布尔类型:
BOOLEAN
- 数组类型: 任何基本类型都可以加上
[]
成为数组类型, 例如INTEGER[]
- JSON类型:
JSON
,JSONB
- UUID类型:
UUID
- 枚举类型:
CREATE TYPE
示例:
sql
CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
CREATE TABLE person (
name text,
current_mood mood
);
2.3. ALTER TABLE
ALTER TABLE
语句用于修改现有表的结构。
- 添加列:
sql
ALTER TABLE products ADD COLUMN description TEXT;
- 删除列:
sql
ALTER TABLE products DROP COLUMN description;
- 修改列的数据类型:
sql
ALTER TABLE products ALTER COLUMN price TYPE NUMERIC(12, 4);
- 添加约束:
sql
ALTER TABLE products ADD CONSTRAINT price_positive CHECK (price > 0);
- 重命名数据表
sql
ALTER TABLE old_table_name RENAME TO new_table_name;
2.4. DROP TABLE
DROP TABLE
语句用于删除表。
sql
DROP TABLE products;
DROP TABLE IF EXISTS product;
可以避免product
不存在时的错误。
2.5. CREATE INDEX
CREATE INDEX
语句用于创建索引以加速查询。
sql
CREATE INDEX idx_product_name ON products (product_name);
可以在多个列上创建复合索引:
sql
CREATE INDEX idx_product_category ON products (product_name, category_id);
2.6. DROP INDEX
DROP INDEX
用于删除索引
sql
DROP INDEX idx_product_name;
3. 数据操作语言 (DML)
DML语句用于查询和修改数据。
3.1. SELECT
SELECT
语句用于从表中检索数据。
sql
SELECT product_id, product_name, price FROM products;
- WHERE子句: 过滤结果。
sql
SELECT * FROM products WHERE price > 100;
- ORDER BY子句: 对结果排序。
sql
SELECT * FROM products ORDER BY price DESC;
ASC
是默认排序方式(升序)
- LIMIT子句: 限制返回的行数。
sql
SELECT * FROM products LIMIT 10;
- OFFSET子句: 跳过指定数量的行。
sql
SELECT * FROM products OFFSET 5 LIMIT 10; -- 跳过前5行,返回接下来的10行
- DISTINCT 关键字: 返回唯一不同的值。
sql
SELECT DISTINCT category_id FROM products;
3.2. INSERT
INSERT
语句用于向表中插入新行。
sql
INSERT INTO products (product_name, price, category_id) VALUES ('Laptop', 1200.00, 1);
如果插入的值和数据表列的顺序一致,可以不指定列名。
3.3. UPDATE
UPDATE
语句用于修改现有行。
sql
UPDATE products SET price = 1300.00 WHERE product_id = 1;
3.4. DELETE
DELETE
语句用于删除行。
sql
DELETE FROM products WHERE product_id = 1;
3.5 JOIN 操作
JOIN操作用于合并多个表中的数据。
- INNER JOIN: 返回两个表中匹配的行。
不同JOIN操作的直观比较如下:
- INNER JOIN: 仅返回两个表中存在匹配的行。
- LEFT (OUTER) JOIN: 返回左表中的所有行,以及右表中匹配的行。如果右表中没有匹配项,则右侧列返回NULL。
- RIGHT (OUTER) JOIN: 返回右表中的所有行,以及左表中匹配的行。如果左表中没有匹配项,则左侧列返回NULL。
- FULL (OUTER) JOIN: 返回左表和右表中的所有行。如果某一行在另一个表中没有匹配项,则另一侧的列返回NULL。
sql
SELECT p.product_name, c.category_name
FROM products p
INNER JOIN categories c ON p.category_id = c.category_id;
- LEFT (OUTER) JOIN: 返回左表中的所有行,以及右表中匹配的行。如果右表中没有匹配项,则右侧列返回NULL。
sql
SELECT p.product_name, c.category_name
FROM products p
LEFT JOIN categories c ON p.category_id = c.category_id;
- RIGHT (OUTER) JOIN: 返回右表中的所有行,以及左表中匹配的行。如果左表中没有匹配项,则左侧列返回NULL。
sql
SELECT p.product_name, c.category_name
FROM products p
RIGHT JOIN categories c ON p.category_id = c.category_id;
- FULL (OUTER) JOIN: 返回两个表所有行,没有匹配的地方用NULL填充。
sql
SELECT p.product_name, c.category_name
FROM products p
FULL OUTER JOIN categories c ON p.category_id = c.category_id;
3.6. 子查询
子查询是嵌套在另一个查询中的查询。
sql
SELECT product_name, price
FROM products
WHERE price > (SELECT AVG(price) FROM products);
3.7. 聚合函数
聚合函数对一组值执行计算并返回单个值。
COUNT
: 计算行数。
sql
SELECT COUNT(*) FROM products;
SUM
: 计算总和。
sql
SELECT SUM(price) FROM products;
AVG
: 计算平均值。
sql
SELECT AVG(price) FROM products;
MIN
: 计算最小值。
sql
SELECT MIN(price) FROM products;
MAX
: 计算最大值。
sql
SELECT MAX(price) FROM products;
- GROUP BY 子句: 将结果分组。
sql
SELECT category_id, AVG(price) FROM products GROUP BY category_id;
- HAVING 子句: 过滤分组后的结果。
sql
SELECT category_id, AVG(price) FROM products GROUP BY category_id HAVING AVG(price) > 50;
4. 数据控制语言 (DCL)
DCL语句用于控制数据库的访问权限。
4.1. GRANT
GRANT
语句用于授予用户权限。
sql
GRANT SELECT, INSERT ON products TO someuser;
4.2. REVOKE
REVOKE
语句用于撤销用户权限。
sql
REVOKE INSERT ON products FROM someuser;
5. 事务控制语句
事务控制语句用于管理数据库事务。
5.1. BEGIN
BEGIN
语句用于开始一个事务。
sql
BEGIN;
5.2. COMMIT
COMMIT
语句用于提交事务。
sql
COMMIT;
5.3. ROLLBACK
ROLLBACK
语句用于回滚事务。
sql
ROLLBACK;
在事务中可以设置保存点SAVEPOINT my_savepoint;
,然后选择回滚到保存点ROLLBACK TO my_savepoint;
。
6. 高级特性
6.1. 窗口函数
窗口函数对一组行(“窗口”)执行计算,而不会导致行被分组为单个输出行。
sql
SELECT
product_name,
price,
AVG(price) OVER (PARTITION BY category_id) AS avg_price_in_category
FROM products;
PARTITION BY
将数据按照category_id
进行分区。
6.2. 公共表达式 (CTE)
CTE是一个命名的临时结果集,仅在单个查询的执行范围内存在。
sql
WITH expensive_products AS (
SELECT * FROM products WHERE price > 1000
)
SELECT * FROM expensive_products;
6.3. 存储过程和函数
PostgreSQL 允许创建存储过程和函数,这些过程和函数是用 PL/pgSQL(或其他支持的语言)编写的,并存储在数据库服务器中。
创建函数:
```sql
CREATE FUNCTION get_total_sales(product_id INT)
RETURNS NUMERIC AS $$
DECLARE
total_sales NUMERIC;
BEGIN
SELECT SUM(price) INTO total_sales
FROM order_items
WHERE product_id = $1;
RETURN total_sales;
END;
$$ LANGUAGE plpgsql;
调用函数:
sql
SELECT get_total_sales(1);
存储过程不返回值:
sql
CREATE PROCEDURE update_product_price(product_id INT, new_price NUMERIC)
AS $$
BEGIN
UPDATE products SET price = new_price WHERE id = product_id;
COMMIT;
END;
$$ LANGUAGE plpgsql;
```
6.4 触发器
触发器是数据库中定义的特殊类型的存储过程,它会在指定的数据库事件(例如 INSERT
、UPDATE
或 DELETE
操作)发生时自动执行。
```sql
CREATE FUNCTION log_product_changes()
RETURNS TRIGGER AS $$
BEGIN
IF (TG_OP = 'UPDATE') THEN
INSERT INTO product_audit_log (product_id, old_price, new_price, changed_on)
VALUES (OLD.id, OLD.price, NEW.price, NOW());
RETURN NEW;
ELSIF (TG_OP = 'INSERT') THEN
INSERT INTO product_audit_log (product_id, old_price, new_price, changed_on)
VALUES (NEW.id, null, NEW.price, NOW());
RETURN NEW;
END IF;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER product_update_trigger
AFTER UPDATE OR INSERT ON products
FOR EACH ROW
EXECUTE FUNCTION log_product_changes();
```
7. 内容补充
本教程详细阐述了PostgreSQL中的SQL语法,涵盖了数据定义、数据操作、数据控制和事务控制等方面。同时,通过大量代码示例,说明了DDL语句构建和修改数据库结构、DML语句查询和修改数据、DCL语句控制数据库访问权限,以及事务控制语句管理事务。
此外,本教程还介绍了PostgreSQL的一些高级特性,如窗口函数、公共表达式和触发器。掌握这些SQL语法和高级特性,将有助于开发人员和数据库管理员更有效地利用PostgreSQL管理和操作数据。
希望读者通过此教程对PostgreSQL的SQL语法有更全面和深入的了解。