基础SQL语法:SELECT、INSERT、UPDATE、DELETE详解

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');

八、安全最佳实践

  1. 始终使用WHERE条件:除非你真的想操作所有记录
  2. 操作前先备份:重要数据操作前做好备份
  3. 使用事务:保证操作的原子性
  4. 权限控制:生产环境避免使用高权限账户
  5. 参数化查询:防止SQL注入攻击

总结

通过本章学习,你应该已经掌握了SQL的四大基础操作:

  • SELECT:精确查询需要的数据
  • INSERT:安全地添加新记录
  • UPDATE:准确地修改现有数据
  • DELETE:谨慎地删除不再需要的数据

能力越大,责任越大。在生产环境中执行UPDATE和DELETE操作时,一定要格外小心,遵循"先查询,后操作"的原则。

相关推荐
Leon-Ning Liu34 分钟前
Oracle 19c RAC ASM 密码文件恢复方案一: asmcmd --nocp credfix 命令修复
数据库·oracle
赵庆明老师35 分钟前
用缓存功能解决.NET程序访问数据库的性能问题
数据库·缓存·.net
时光追逐者37 分钟前
排查 EF 保存数据时提示:Validation failed for one or more entities 的问题
数据库·c#·.net·ef
北慕阳39 分钟前
选择采购单按钮
前端·javascript·数据库
怪侠Kevin39 分钟前
seata事务集成kafka
数据库·分布式·kafka
时光追逐者43 分钟前
在 .NET 中将 EF Core 升级到 9.0.5 MySQL 连接提示 get_LockReleaseBehavior
数据库·mysql·c#·.net·ef core
卜锦元1 小时前
docker 部署南大通用 GBase 8sV8.8
运维·数据库·docker·容器·部署·运维开发
代码or搬砖1 小时前
Redis下载以及Redis常用命令
数据库·redis·缓存
118路司机1 小时前
ClickHouse常用DDL
数据库·clickhouse