SQL(Structured Query Language)是与数据库沟通的标准语言。可以把数据库想象成一个超级智能的文件柜,而SQL就是你向文件柜管理员发出的指令。学会了SQL,你就能让数据库帮你存储、查找、修改和删除数据。
今天我们来深入学习SQL中最核心的四个命令:SELECT(查询)、INSERT(插入)、UPDATE(更新)、DELETE(删除)。
一、SELECT - 数据查询的艺术
1.1 基础查询语法
sql
-- 查询users表中的所有数据
SELECT * FROM users;
解析:
SELECT:告诉数据库你要查询数据*:代表所有列FROM:指定从哪个表查询users:表名;:SQL语句结束符
1.2 选择特定列查询
sql
-- 只查询姓名和年龄列
SELECT name, age FROM users;
-- 使用表名前缀(推荐在多表查询时使用)
SELECT users.name, users.age FROM users;
应用场景: 当表中有很多列,但你只需要其中几列时,指定列名可以提高查询效率。
1.3 使用WHERE子句进行条件过滤
sql
-- 简单条件查询
SELECT * FROM users WHERE age > 18;
-- 多个条件组合
SELECT * FROM users WHERE age > 18 AND city = '北京';
-- 使用OR条件
SELECT * FROM users WHERE age < 18 OR age > 60;
-- 模糊查询
SELECT * FROM users WHERE name LIKE '张%'; -- 查找姓张的用户
SELECT * FROM users WHERE email LIKE '%@gmail.com'; -- 查找Gmail用户
-- 范围查询
SELECT * FROM users WHERE age BETWEEN 18 AND 25;
SELECT * FROM users WHERE age IN (18, 20, 22); -- 年龄为18、20或22
1.4 结果排序和限制
sql
-- 单字段排序
SELECT * FROM users ORDER BY age DESC; -- 按年龄降序
SELECT * FROM users ORDER BY create_time ASC; -- 按创建时间升序
-- 多字段排序
SELECT * FROM users ORDER BY age DESC, name ASC; -- 先按年龄降序,年龄相同按姓名升序
-- 限制返回条数
SELECT * FROM users LIMIT 10; -- 返回前10条
SELECT * FROM users LIMIT 10, 20; -- 从第10条开始返回20条(跳过前10条)
1.5 去重和聚合
sql
-- 去除重复值
SELECT DISTINCT city FROM users; -- 查询所有不重复的城市
-- 使用聚合函数
SELECT COUNT(*) FROM users; -- 统计总用户数
SELECT AVG(age) FROM users; -- 计算平均年龄
SELECT MAX(age) FROM users; -- 最大年龄
SELECT MIN(age) FROM users; -- 最小年龄
SELECT SUM(salary) FROM users; -- 工资总和
二、INSERT - 数据插入详解
2.1 插入单条数据
sql
-- 完整字段插入
INSERT INTO users (name, age, email, city)
VALUES ('张三', 25, 'zhangsan@example.com', '北京');
-- 自动递增字段可以省略
INSERT INTO users (name, age, email)
VALUES ('李四', 30, 'lisi@example.com');
注意事项:
- 字段名和值必须一一对应
- 字符串和日期类型需要用单引号括起来
- 数字类型直接书写
- NULL值可以直接使用NULL
2.2 批量插入数据
sql
-- 一次性插入多条数据
INSERT INTO users (name, age, email) VALUES
('王五', 28, 'wangwu@example.com'),
('赵六', 22, 'zhaoliu@example.com'),
('钱七', 35, 'qianqi@example.com');
优势: 批量插入比多次单条插入效率高很多。
2.3 插入查询结果
sql
-- 从另一张表导入数据
INSERT INTO adult_users (name, age, email)
SELECT name, age, email FROM users WHERE age >= 18;
2.4 插入时的常见错误
sql
-- 错误:字段和值数量不匹配
INSERT INTO users (name, age, email) VALUES ('张三', 25);
-- 错误:字符串使用双引号(某些数据库不支持)
INSERT INTO users (name) VALUES ("张三");
-- 错误:违反唯一约束
INSERT INTO users (email) VALUES ('existing@email.com'); -- 如果email已存在
-- 正确写法
INSERT INTO users (name, age, email) VALUES ('张三', 25, 'zhangsan@example.com');
三、UPDATE - 数据更新技巧
3.1 基础更新操作
sql
-- 更新特定记录
UPDATE users SET age = 26 WHERE name = '张三';
-- 更新多个字段
UPDATE users
SET age = 27, city = '上海', email = 'new_email@example.com'
WHERE name = '李四';
3.2 基于表达式更新
sql
-- 数值计算
UPDATE products SET price = price * 0.9; -- 所有商品打9折
UPDATE employees SET salary = salary + 1000 WHERE department = '技术部';
-- 字符串操作
UPDATE users SET email = CONCAT(username, '@company.com') WHERE email IS NULL;
-- 日期操作
UPDATE orders SET expire_date = DATE_ADD(create_date, INTERVAL 30 DAY)
WHERE expire_date IS NULL;
3.3 使用子查询更新
sql
-- 根据其他表的数据更新当前表
UPDATE employees
SET salary = salary * 1.1
WHERE department_id IN (
SELECT id FROM departments WHERE name = '研发部'
);
3.4 更新操作的安全注意事项
sql
-- 危险操作:忘记WHERE条件会更新所有记录!
UPDATE users SET status = 'inactive'; -- 所有用户都会被设置为未激活!
-- 安全做法:先查询确认,再更新
-- 1. 先查询要更新的记录
SELECT * FROM users WHERE last_login < '2024-01-01';
-- 2. 执行更新
UPDATE users SET status = 'inactive'
WHERE last_login < '2024-01-01';
-- 3. 使用事务,便于回滚
BEGIN;
UPDATE users SET status = 'inactive' WHERE last_login < '2024-01-01';
-- 检查结果,如果没问题
COMMIT;
-- 如果有问题
ROLLBACK;
四、DELETE - 数据删除操作
4.1 条件删除
sql
-- 删除特定记录
DELETE FROM users WHERE name = '张三';
-- 删除满足多个条件的记录
DELETE FROM users WHERE age < 18 AND status = 'inactive';
-- 使用子查询删除
DELETE FROM orders
WHERE customer_id IN (
SELECT id FROM customers WHERE status = 'closed'
);
4.2 清空表数据
sql
-- 删除表中所有数据(可回滚)
DELETE FROM users;
-- 清空表(不可回滚,效率更高)
TRUNCATE TABLE users;
DELETE vs TRUNCATE:
DELETE:逐行删除,可回滚,可带WHERE条件TRUNCATE:直接清空表,不可回滚,重置自增ID
4.3 删除操作的最佳实践
sql
-- 推荐的安全删除流程:
-- 1. 先备份重要数据
CREATE TABLE users_backup AS SELECT * FROM users WHERE age < 18;
-- 2. 使用事务
BEGIN;
-- 3. 先查询确认要删除的数据
SELECT COUNT(*) FROM users WHERE age < 18;
-- 4. 执行删除
DELETE FROM users WHERE age < 18;
-- 5. 确认删除结果
SELECT COUNT(*) FROM users WHERE age < 18;
-- 6. 提交或回滚
COMMIT; -- 确认无误后提交
-- 或者 ROLLBACK; -- 发现问题时回滚
五、综合示例
让我们通过一个完整的例子来巩固所学知识:
sql
-- 创建学生表
CREATE TABLE students (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
age INT,
class VARCHAR(20),
math_score DECIMAL(4,1),
english_score DECIMAL(4,1),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 插入初始数据
INSERT INTO students (name, age, class, math_score, english_score) VALUES
('小明', 18, '高三1班', 85.5, 92.0),
('小红', 17, '高三2班', 92.0, 88.5),
('小刚', 18, '高三1班', 78.5, 82.0),
('小丽', 17, '高三2班', 88.0, 91.5),
('小华', 19, '高三3班', 76.0, 79.5);
-- 查询操作示例
-- 1. 查询所有学生信息
SELECT * FROM students;
-- 2. 查询数学成绩前3名的学生
SELECT name, math_score FROM students ORDER BY math_score DESC LIMIT 3;
-- 3. 查询每个班级的平均成绩
SELECT class,
AVG(math_score) as avg_math,
AVG(english_score) as avg_english
FROM students
GROUP BY class;
-- 更新操作示例
-- 1. 给高三1班所有学生的数学成绩加5分
UPDATE students
SET math_score = math_score + 5
WHERE class = '高三1班';
-- 2. 更新小红的英语成绩
UPDATE students
SET english_score = 95.0
WHERE name = '小红';
-- 删除操作示例
-- 删除英语成绩低于60分的学生
DELETE FROM students WHERE english_score < 60;
六、常见错误和调试技巧
6.1 语法错误排查
sql
-- 常见错误1:缺少逗号
INSERT INTO users (name age) VALUES ('张三', 25); -- name和age之间缺少逗号
-- 正确
INSERT INTO users (name, age) VALUES ('张三', 25);
-- 常见错误2:字符串引号不匹配
UPDATE users SET name = '张三 WHERE id = 1; -- 缺少结束引号
-- 正确
UPDATE users SET name = '张三' WHERE id = 1;
-- 常见错误3:使用保留字作为字段名
INSERT INTO users (order) VALUES ('first'); -- order是SQL保留字
-- 正确:使用反引号
INSERT INTO users (`order`) VALUES ('first');
6.2 逻辑错误调试
sql
-- 调试UPDATE和DELETE的推荐步骤:
-- 1. 先用SELECT测试WHERE条件
SELECT * FROM users WHERE age > 60; -- 确认会影响到哪些记录
-- 2. 使用事务进行安全操作
START TRANSACTION;
-- 3. 执行操作
UPDATE users SET status = 'retired' WHERE age > 60;
-- 4. 检查结果
SELECT * FROM users WHERE status = 'retired';
-- 5. 确认无误后提交,有问题则回滚
COMMIT;
-- 或 ROLLBACK;
七、性能优化建议
7.1 查询优化
sql
-- 不推荐:使用SELECT *
SELECT * FROM users WHERE age > 18;
-- 推荐:只选择需要的列
SELECT name, age FROM users WHERE age > 18;
-- 不推荐:在WHERE条件中使用函数
SELECT * FROM users WHERE YEAR(create_time) = 2024;
-- 推荐:使用范围查询
SELECT * FROM users WHERE create_time >= '2024-01-01' AND create_time < '2025-01-01';
7.2 批量操作优化
sql
-- 不推荐:循环单条插入
INSERT INTO users (name) VALUES ('user1');
INSERT INTO users (name) VALUES ('user2');
INSERT INTO users (name) VALUES ('user3');
-- 推荐:批量插入
INSERT INTO users (name) VALUES
('user1'),
('user2'),
('user3');
八、安全最佳实践
- 始终使用WHERE条件:除非你真的想操作所有记录
- 操作前先备份:重要数据操作前做好备份
- 使用事务:保证操作的原子性
- 权限控制:生产环境避免使用高权限账户
- 参数化查询:防止SQL注入攻击
总结
通过本章学习,你应该已经掌握了SQL的四大基础操作:
- SELECT:精确查询需要的数据
- INSERT:安全地添加新记录
- UPDATE:准确地修改现有数据
- DELETE:谨慎地删除不再需要的数据
能力越大,责任越大。在生产环境中执行UPDATE和DELETE操作时,一定要格外小心,遵循"先查询,后操作"的原则。