SQL(结构化查询语言)数据库安装与使用
首先推荐一个不错的SQL语句指导和练习网站:SQLZoo
PostgreSQL 数据库安装#
PostgreSQL: The World’s Most Advanced Open Source Relational Database
PostgreSQL 是一个开源关系型数据库管理系统(Relational Database Management System, RDBMS)
以稳定性、标准兼容性和丰富的数据类型支持而闻名, 被广泛应用于 Web 开发、数据分析以及企业级应用。
- 安装后后添加路径到环境变量
D:\Database\PostgreSQL\bin- 验证版本
psql --version初识 表、数据库、SQL#
表的基础结构#
表(Table)是数据库中存储数据的基本单位,可以理解为一个横纵方向的二维表格。
例如用户信息表:
| id | username | |
|---|---|---|
| 1 | Alice | alice@example.com |
| 2 | Bob | bob@example.com |
| 3 | Charlie | charlie@example.com |
其中:
- 每一列(Column)表示一个字段(Field)
- 每一行(Row)表示一条记录(Record)
- 每张表通常会有主键(Primary Key)用于唯一标识记录
数据库的基础结构#
数据库(Database)是多个表的集合,用于组织和管理数据。
一个简单的网站数据库可能包含多个表:
mydb
├── users
├── articles
├── comments
└── categories
其中:
- users 表存储用户信息
- articles 表存储文章信息
- comments 表存储评论信息
- categories 表存储分类信息
数据库负责维护这些表之间的关系,并保证数据的一致性与安全性。
SQL 基础概念#
SQL(Structured Query Language,结构化查询语言)是操作关系型数据库的标准语言。
通过 SQL 可以完成:
- 创建数据库和表(CREATE)
- 查询数据(SELECT)
- 插入数据(INSERT)
- 更新数据(UPDATE)
- 删除数据(DELETE)
例如:
SELECT * FROM users;表示查询 users 表中的所有数据。 SQL 是学习 PostgreSQL、MySQL、SQLite 等关系型数据库的基础工具。
PostgreSQL 基础操作#
1. 创建数据库与表#
-- 创建数据库CREATE DATABASE mydb;
-- 切换数据库\c mydb
-- 创建表CREATE TABLE users ( id SERIAL PRIMARY KEY, username VARCHAR(60) NOT NULL, email VARCHAR(100) UNIQUE NOT NULL, age INT, created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP);- 注意:列的格式为:
字段名数据类型[(长度)][约束/修饰符]。
2. 删除数据库与表,或清空表#
-- 删除数据库(不能删除当前连接的数据库)DROP DATABASE mydb;
-- 删除表(包括表结构和数据)DROP TABLE exTable;
-- 清空表数据,但保留表结构 (比 DELETE 快,但不记录行日志)TRUNCATE TABLE exTable;--3. 表添加新列,修改数据类型#
-- 添加新列:ALTER TABLE exTable ADD COLUMN age INT;
-- 修改数据类型:ALTER TABLE exTable ALTER COLUMN email TYPE VARCHAR(255);4. 查增改删数据#
- 查
-- 查询所有数据SELECT * FROM exTable;
-- 条件查询SELECT username, emailFROM exTableWHERE id > 1;
-- 模糊查询 (ILIKE 不区分大小写,PostgreSQL 特色)SELECT username, email FROM exTable WHERE username ILIKE 'tech%';
-- 排序与限制,默认升序,DESC为降序SELECT * FROM exTableORDER BY created_time DESCLIMIT 6;- 增
-- 插入一行数据INSERT INTO exTable (username, email)VALUES ('alice', 'alice@example.com');
-- 插入多行INSERT INTO exTable (username, email)VALUES('bob', 'bob@example.com'),('charlie', 'charlie@example.com');- 改
UPDATE exTableSET email = 'alice_new@example.com'WHERE username = 'alice';- 对表进行修改时,务必限定范围,否则会更新全表信息
- 删
DELETE FROM exTableWHERE username = 'charlie';PostgreSQL 进阶基础(T+1)#
前置:已掌握建表、增删改查基础操作
本章目标:写出更精准的查询,理解数据约束,初步接触多表关联
多条件组合查询:AND / OR / NOT#
-- AND:同时满足SELECT * FROM usersWHERE age >= 18 AND age <= 30;
-- OR:满足其中一个SELECT * FROM usersWHERE username = 'alice' OR username = 'bob';
-- NOT:排除SELECT * FROM usersWHERE NOT age < 18;范围与列表:BETWEEN / IN#
-- BETWEEN(含两端)SELECT * FROM usersWHERE age BETWEEN 18 AND 30;
-- IN(等同于多个 OR,更简洁)SELECT * FROM usersWHERE username IN ('alice', 'bob', 'charlie');
-- NOT IN(排除列表)SELECT * FROM usersWHERE username NOT IN ('alice', 'bob');空值判断:IS NULL / IS NOT NULL#
-- 查找没有填写年龄的用户(注意:不能用 = NULL)SELECT * FROM usersWHERE age IS NULL;
-- 查找已填写年龄的用户SELECT * FROM usersWHERE age IS NOT NULL;NULL 不等于空字符串
'',也不等于0,是”未知值”,只能用 IS NULL 判断
聚合函数:对一组数据做统计#
| 函数 | 作用 |
|---|---|
COUNT() | 计数 |
SUM() | 求和 |
AVG() | 平均值 |
MAX() | 最大值 |
MIN() | 最小值 |
-- 一共有多少用户SELECT COUNT(*) FROM users;
-- 用户的平均年龄SELECT AVG(age) FROM users;
-- 年龄最大和最小的用户SELECT MAX(age), MIN(age) FROM users;
-- 注意:COUNT(*) 计所有行,COUNT(age) 会跳过 NULLSELECT COUNT(*), COUNT(age) FROM users;GROUP BY:分组统计#
把数据按某列分组,再对每组做聚合计算
-- 先创建一张订单表来演示CREATE TABLE orders ( id SERIAL PRIMARY KEY, username VARCHAR(60) NOT NULL, product VARCHAR(60), amount INT, created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
INSERT INTO orders (username, product, amount) VALUES('alice', 'book', 120),('alice', 'pen', 30),('bob', 'book', 120),('bob', 'bag', 200),('charlie','pen', 30);-- 每个用户各消费了多少次SELECT username, COUNT(*) AS order_countFROM ordersGROUP BY username;
-- 每个用户的总消费金额SELECT username, SUM(amount) AS total_spentFROM ordersGROUP BY username;输出示例:
| username | total_spent |
|---|---|
| alice | 150 |
| bob | 320 |
| charlie | 30 |
查询执行顺序(重要!)#
很多初学者写出报错 SQL,往往是因为搞错了执行顺序:
FROM → 确定数据来源WHERE → 过滤原始行GROUP BY → 分组HAVING → 过滤分组结果SELECT → 选取列(别名在这里才生效)ORDER BY → 排序LIMIT → 限制条数-- 常见错误示例:WHERE 里用了 SELECT 里定义的别名-- ❌ 错误:WHERE 在 SELECT 之前执行,total_spent 还不存在SELECT username, SUM(amount) AS total_spentFROM ordersWHERE total_spent > 100 -- 报错!GROUP BY username;
-- ✅ 正确:用 HAVINGSELECT username, SUM(amount) AS total_spentFROM ordersGROUP BY usernameHAVING SUM(amount) > 100;外键(Foreign Key):表之间的纽带#
外键用于约束两张表之间的关系,防止出现”孤儿数据”
-- 重建 users 表(如果已存在先删除)DROP TABLE IF EXISTS orders;DROP TABLE IF EXISTS users;
CREATE TABLE users ( id SERIAL PRIMARY KEY, username VARCHAR(60) NOT NULL, email VARCHAR(100) UNIQUE NOT NULL);
-- orders 表的 user_id 指向 users 表的 idCREATE TABLE orders ( id SERIAL PRIMARY KEY, user_id INT REFERENCES users(id), -- 外键 product VARCHAR(60), amount INT);外键的保护效果:
INSERT INTO users (username, email) VALUES ('alice', 'alice@example.com');
-- ✅ alice 的 id 是 1,可以正常插入INSERT INTO orders (user_id, product, amount) VALUES (1, 'book', 120);
-- ❌ 报错:user_id=999 在 users 表里不存在INSERT INTO orders (user_id, product, amount) VALUES (999, 'pen', 30);给列和表起别名:AS#
-- 列别名(让输出更易读)SELECT username AS 用户名, SUM(amount) AS 总消费FROM ordersJOIN users ON orders.user_id = users.idGROUP BY username;
-- 表别名(简化长表名,多表联查时常用)SELECT u.username, o.product, o.amountFROM users AS uJOIN orders AS o ON u.id = o.user_id;本章练习#
用以下两张表完成练习:
-- 准备数据INSERT INTO users (username, email) VALUES('alice', 'alice@example.com'),('bob', 'bob@example.com'),('charlie', 'charlie@example.com');
INSERT INTO orders (user_id, product, amount) VALUES(1, 'book', 120),(1, 'pen', 30),(2, 'book', 120),(2, 'bag', 200);-- charlie 没有订单- 查询所有用户名和他们的订单总金额,按总金额降序排列
- 找出总消费超过 100 的用户
- 查询所有用户,没有订单的也要显示(提示:LEFT JOIN)
- 统计每种商品各卖出了几次
本章知识结构#
T+1 SQL基础├── 条件查询│ ├── AND / OR / NOT│ ├── BETWEEN / IN│ └── IS NULL / IS NOT NULL├── 聚合统计│ ├── COUNT / SUM / AVG / MAX / MIN│ ├── GROUP BY│ └── HAVING├── 查询执行顺序│ └── FROM→WHERE→GROUP BY→HAVING→SELECT→ORDER BY→LIMIT└── 多表关联 ├── 外键 REFERENCES ├── INNER JOIN ├── LEFT JOIN └── 列/表别名 AS