网站首页 > 文章精选 正文
概述
通过这些Top 20 SQL面试题及答案来破解您的SQL面试。包含详细解释、示例和关键差异,适用于应届生和有经验的候选人。
1. 什么是SQL?
答案:
SQL(结构化查询语言)是用于管理和操作数据库的标准语言。
示例:
SELECT * FROM employees;
2.DELETE、TRUNCATE和DROP之间有什么区别?
命令描述可回滚影响结构DELETE删除选定的行是否TRUNCATE快速删除所有行否否DROP删除整个表否是
3. SQL语句有哪些不同类型?
答案:
- DDL – 数据定义语言(CREATE、ALTER、DROP)
- DML – 数据操作语言(INSERT、UPDATE、DELETE)
- DQL – 数据查询语言(SELECT)
- DCL – 数据控制语言(GRANT、REVOKE)
- TCL – 事务控制语言(COMMIT、ROLLBACK)
4. 什么是主键?
答案:
主键是唯一标识表中每一行的列(或列集合)。
示例:
CREATE TABLE students (
student_id INT PRIMARY KEY,
name VARCHAR(50)
);
5. 什么是外键?
答案:
外键是一个表中的列,指向另一个表中的主键,用于建立关系。
示例:
FOREIGN KEY (student_id) REFERENCES students(student_id)
6.WHERE和HAVING之间有什么区别?
子句用例作用于WHERE在分组前过滤行行HAVING在GROUP BY后过滤聚合数据
示例:
SELECT dept, COUNT(*) FROM employees
GROUP BY dept
HAVING COUNT(*) > 5;
7. SQL中的JOIN是什么?
答案:
JOIN用于组合两个或多个表中的行。
连接类型描述INNER JOIN匹配两个表中的行LEFT JOIN左表的所有行 + 右表的匹配行RIGHT JOIN右表的所有行 + 左表的匹配行FULL JOIN两个表中所有匹配 + 不匹配的行
示例:
SELECT e.name, d.name
FROM employees e
INNER JOIN departments d ON e.dept_id = d.id;
8.UNION和UNION ALL之间有什么区别?
关键字重复项更快UNION移除否UNION ALL保留是
9. 什么是规范化?
答案:
规范化是减少数据冗余和提高数据完整性的过程。
范式:
- 1NF:原子列
- 2NF:无部分依赖
- 3NF:无传递依赖
10. 什么是子查询?
答案:
子查询是嵌套在另一个查询中的查询。
示例:
SELECT name FROM students
WHERE id IN (SELECT student_id FROM enrollments);
11.IN和EXISTS之间有什么区别?
- IN:检查列表或子查询中的值。
- EXISTS:检查子查询是否返回至少一行。
12. 什么是索引?
答案:
索引通过允许更快的搜索和检索来提高查询性能。
示例:
CREATE INDEX idx_name ON employees(name);
13. 什么是视图?
答案:
视图是基于SQL查询的虚拟表。
示例:
CREATE VIEW active_employees AS
SELECT * FROM employees WHERE status = 'active';
14. 什么是存储过程?
答案:
存储过程是预编译的SQL语句组。
示例:
CREATE PROCEDURE GetEmployees()
AS
BEGIN
SELECT * FROM employees;
END;
15.CHAR和VARCHAR之间有什么区别?
类型固定/可变存储CHAR(n)固定长度始终n字节VARCHAR(n)可变长度最多n字节
16. SQL中的聚合函数有哪些?
答案:
聚合函数对多行执行计算。
函数用途SUM()求和AVG()平均值COUNT()计数行MAX()最大值MIN()最小值
17. 什么是约束?
答案:
约束对数据列强制执行规则。
- NOT NULL
- UNIQUE
- PRIMARY KEY
- FOREIGN KEY
- CHECK
- DEFAULT
18.BETWEEN和IN之间有什么区别?
- BETWEEN检查范围。
- IN检查特定值。
示例:
-- BETWEEN
SELECT * FROM students WHERE age BETWEEN 18 AND 25;
-- IN
SELECT * FROM students WHERE city IN ('Delhi', 'Mumbai');
19. SQL中的事务是什么?
答案:
事务是一个工作单元,要么完全完成,要么完全失败。
命令:
- BEGIN TRANSACTION
- COMMIT
- ROLLBACK
20. 如何优化慢SQL查询?
答案:
- 使用索引
- 避免SELECT *
- 正确使用JOIN
- 避免不必要的子查询
- 使用EXPLAIN或QUERY PLAN分析
详细代码示例
数据库表结构示例
-- 创建学生表
CREATE TABLE students (
student_id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE,
age INT CHECK (age >= 0),
department_id INT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (department_id) REFERENCES departments(department_id)
);
-- 创建部门表
CREATE TABLE departments (
department_id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
location VARCHAR(100)
);
-- 创建课程表
CREATE TABLE courses (
course_id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
credits INT DEFAULT 3,
instructor_id INT
);
-- 创建学生课程关联表
CREATE TABLE student_courses (
student_id INT,
course_id INT,
grade DECIMAL(3,2),
enrollment_date DATE,
PRIMARY KEY (student_id, course_id),
FOREIGN KEY (student_id) REFERENCES students(student_id),
FOREIGN KEY (course_id) REFERENCES courses(course_id)
);
复杂查询示例
-- 1. 使用JOIN查询学生和部门信息
SELECT
s.name AS student_name,
s.email,
d.name AS department_name
FROM students s
LEFT JOIN departments d ON s.department_id = d.department_id
WHERE s.age BETWEEN 18 AND 25;
-- 2. 使用子查询查找平均分高于班级平均分的学生
SELECT
s.name,
sc.grade
FROM students s
JOIN student_courses sc ON s.student_id = sc.student_id
WHERE sc.grade > (
SELECT AVG(grade)
FROM student_courses
WHERE course_id = sc.course_id
);
-- 3. 使用聚合函数和GROUP BY
SELECT
d.name AS department,
COUNT(s.student_id) AS student_count,
AVG(s.age) AS avg_age
FROM departments d
LEFT JOIN students s ON d.department_id = s.department_id
GROUP BY d.department_id, d.name
HAVING COUNT(s.student_id) > 5;
-- 4. 使用窗口函数
SELECT
s.name,
sc.grade,
RANK() OVER (PARTITION BY sc.course_id ORDER BY sc.grade DESC) AS rank_in_course
FROM students s
JOIN student_courses sc ON s.student_id = sc.student_id;
-- 5. 使用CTE(公用表表达式)
WITH high_performers AS (
SELECT student_id, AVG(grade) as avg_grade
FROM student_courses
GROUP BY student_id
HAVING AVG(grade) >= 3.5
)
SELECT
s.name,
hp.avg_grade
FROM students s
JOIN high_performers hp ON s.student_id = hp.student_id;
存储过程和函数示例
-- 创建存储过程
DELIMITER //
CREATE PROCEDURE GetStudentInfo(IN student_id_param INT)
BEGIN
SELECT
s.name,
s.email,
d.name AS department,
COUNT(sc.course_id) AS enrolled_courses,
AVG(sc.grade) AS average_grade
FROM students s
LEFT JOIN departments d ON s.department_id = d.department_id
LEFT JOIN student_courses sc ON s.student_id = sc.student_id
WHERE s.student_id = student_id_param
GROUP BY s.student_id, s.name, s.email, d.name;
END //
DELIMITER ;
-- 创建函数
DELIMITER //
CREATE FUNCTION GetStudentGrade(student_id_param INT, course_id_param INT)
RETURNS DECIMAL(3,2)
READS SQL DATA
DETERMINISTIC
BEGIN
DECLARE student_grade DECIMAL(3,2);
SELECT grade INTO student_grade
FROM student_courses
WHERE student_id = student_id_param
AND course_id = course_id_param;
RETURN COALESCE(student_grade, 0.00);
END //
DELIMITER ;
-- 使用存储过程
CALL GetStudentInfo(1);
-- 使用函数
SELECT GetStudentGrade(1, 101) AS grade;
索引和性能优化示例
-- 创建复合索引
CREATE INDEX idx_student_dept_age ON students(department_id, age);
-- 创建部分索引(MySQL 8.0+)
CREATE INDEX idx_active_students ON students(name) WHERE age >= 18;
-- 分析查询性能
EXPLAIN SELECT * FROM students WHERE department_id = 1 AND age > 20;
-- 查看索引使用情况
SHOW INDEX FROM students;
-- 优化查询示例
-- 不好的查询
SELECT * FROM students WHERE name LIKE '%John%';
-- 优化的查询
SELECT student_id, name, email FROM students
WHERE name LIKE 'John%'
LIMIT 10;
事务处理示例
-- 开始事务
START TRANSACTION;
-- 插入新学生
INSERT INTO students (name, email, age, department_id)
VALUES ('张三', 'zhangsan@example.com', 20, 1);
-- 获取新插入的学生ID
SET @new_student_id = LAST_INSERT_ID();
-- 为学生注册课程
INSERT INTO student_courses (student_id, course_id, grade, enrollment_date)
VALUES (@new_student_id, 101, NULL, CURDATE());
-- 提交事务
COMMIT;
-- 错误处理示例
START TRANSACTION;
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
SELECT 'Transaction failed' AS message;
END;
INSERT INTO students (name, email, age, department_id)
VALUES ('李四', 'lisi@example.com', 22, 1);
INSERT INTO student_courses (student_id, course_id, grade, enrollment_date)
VALUES (LAST_INSERT_ID(), 101, NULL, CURDATE());
COMMIT;
SELECT 'Transaction successful' AS message;
END;
面试技巧
1. 准备阶段
- 复习基本的SQL语法和概念
- 练习编写复杂查询
- 理解数据库设计原则
- 熟悉性能优化技巧
2. 面试中
- 仔细阅读问题要求
- 先思考再编码
- 解释你的思路
- 考虑边界情况
- 讨论性能影响
3. 常见陷阱
- 忘记处理NULL值
- 忽略索引的重要性
- 不熟悉事务处理
- 缺乏对数据类型的理解
总结
这20个SQL面试题涵盖了从基础概念到高级特性的各个方面:
- 基础概念:SQL语法、数据类型、约束
- 查询操作:SELECT、JOIN、子查询、聚合函数
- 数据操作:INSERT、UPDATE、DELETE、事务
- 性能优化:索引、查询优化、存储过程
- 数据库设计:规范化、主键、外键
掌握这些概念将帮助您在SQL面试中表现出色,并在实际工作中编写高效、可维护的数据库代码。
猜你喜欢
- 2025-07-10 失业程序员复习python笔记——mysql
- 2025-07-10 MySQL高性能注意事项简述(高性能mysql重点章节)
- 2025-07-10 MySQL触发器介绍(mysql触发器使用)
- 2025-07-10 2021年超详细的java学习路线总结—纯干货分享
- 2025-07-10 MySQL常见错误及解决方法(mysql常见错误提示及解决方法)
- 2025-07-10 MySQL索引失效场景分析与优化(mysql索引何时失效)
- 2025-07-10 MySQL实战:聊聊子查询 vs 联表查询应该如何选择?
- 2025-07-10 SQL 神操作:用 LEFT JOIN 干掉 NOT IN,查询速度直接飙车!
- 2025-07-10 The entangled power of BRICS(the power of dreams)
- 2025-07-10 谁再在 SQL 中写 in 和 not in,直接走人!
- 最近发表
-
- Vue3+Django4全新技术实战全栈项目|高清完结
- 工厂模式+策略模式消除 if else 实战
- 每天一个 Python 库:httpx异步请求,让接口测试飞起来
- 如何高效实现API接口的自动化测试?
- 前端工程化:从“手忙脚乱”到“从容协作”的进化记
- 使用C#创建服务端Web API(c#开发web服务器)
- SpringBoot之旅第四篇-web开发(springboot做web项目)
- 一文读懂SpringMVC(一文读懂新型政策性金融工具)
- Rust Web编程:第十二章 在 Rocket 中重新创建我们的应用程序
- Apache Druid 数据摄取——本地数据和kafka流式数据 一篇文章看懂
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 计算机网络的拓扑结构是指() (45)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)
- mysql数据库面试题 (57)