10道SQL练习题及答案

10道SQL练习题及答案

题目1:基础查询与排序

题目描述:假设有一个学生成绩表,查询所有学生的姓名、科目和成绩,按科目升序,同一科目按成绩降序排列。

建表语句

sql 复制代码
CREATE TABLE IF NOT EXISTS student_scores (
    id INT PRIMARY KEY AUTO_INCREMENT,
    student_name VARCHAR(50) NOT NULL,
    subject VARCHAR(50) NOT NULL,
    score INT NOT NULL
);

插入数据

sql 复制代码
INSERT INTO student_scores (student_name, subject, score) VALUES
('张三', '数学', 85),
('张三', '英语', 92),
('张三', '语文', 78),
('李四', '数学', 90),
('李四', '英语', 88),
('李四', '语文', 95),
('王五', '数学', 76),
('王五', '英语', 80),
('王五', '语文', 85);

答案

sql 复制代码
SELECT student_name, subject, score
FROM student_scores
ORDER BY subject ASC, score DESC;

题目2:聚合函数与分组

题目描述:统计每个科目的平均成绩、最高成绩和最低成绩。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT subject, AVG(score) AS avg_score, MAX(score) AS max_score, MIN(score) AS min_score
FROM student_scores
GROUP BY subject;

题目3:HAVING子句

题目描述:找出平均成绩大于80分的科目及其平均成绩。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT subject, AVG(score) AS avg_score
FROM student_scores
GROUP BY subject
HAVING AVG(score) > 80;

题目4:内连接

题目描述:假设有学生表和班级表,查询每个学生的姓名和所在班级名称。

建表语句

sql 复制代码
CREATE TABLE IF NOT EXISTS classes (
    class_id INT PRIMARY KEY,
    class_name VARCHAR(50) NOT NULL
);

CREATE TABLE IF NOT EXISTS students (
    student_id INT PRIMARY KEY,
    student_name VARCHAR(50) NOT NULL,
    class_id INT NOT NULL,
    FOREIGN KEY (class_id) REFERENCES classes(class_id)
);

插入数据

sql 复制代码
INSERT INTO classes (class_id, class_name) VALUES
(1, '一班'),
(2, '二班'),
(3, '三班');

INSERT INTO students (student_id, student_name, class_id) VALUES
(1, '张三', 1),
(2, '李四', 1),
(3, '王五', 2),
(4, '赵六', 3),
(5, '孙七', 3);

答案

sql 复制代码
SELECT s.student_name, c.class_name
FROM students s
INNER JOIN classes c ON s.class_id = c.class_id;

题目5:左连接

题目描述:查询所有班级及其学生人数,包括没有学生的班级。

使用表:classes、students(同题目4)

答案

sql 复制代码
SELECT c.class_name, COUNT(s.student_id) AS student_count
FROM classes c
LEFT JOIN students s ON c.class_id = s.class_id
GROUP BY c.class_id, c.class_name;

题目6:子查询

题目描述:查询成绩高于数学平均成绩的学生姓名、科目和成绩。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT student_name, subject, score
FROM student_scores
WHERE subject = '数学' AND score > (
    SELECT AVG(score)
    FROM student_scores
    WHERE subject = '数学'
);

题目7:窗口函数

题目描述:为每个学生计算其各科成绩的排名(按成绩降序)。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT student_name, subject, score,
    RANK() OVER (PARTITION BY student_name ORDER BY score DESC) AS subject_rank
FROM student_scores;

题目8:日期函数

题目描述:假设有订单表,查询2023年3月份的订单数量和总金额。

建表语句

sql 复制代码
CREATE TABLE IF NOT EXISTS orders (
    order_id INT PRIMARY KEY AUTO_INCREMENT,
    order_date DATE NOT NULL,
    amount DECIMAL(10,2) NOT NULL
);

插入数据

sql 复制代码
INSERT INTO orders (order_date, amount) VALUES
('2023-02-25', 100.00),
('2023-03-05', 200.00),
('2023-03-15', 150.00),
('2023-03-25', 300.00),
('2023-04-05', 250.00);

答案

sql 复制代码
SELECT COUNT(*) AS order_count, SUM(amount) AS total_amount
FROM orders
WHERE YEAR(order_date) = 2023 AND MONTH(order_date) = 3;

题目9:字符串函数

题目描述:假设有员工表,将员工姓名的首字母大写,其余字母小写,并查询员工编号、处理后的姓名和邮箱。

建表语句

sql 复制代码
CREATE TABLE IF NOT EXISTS employees (
    emp_id INT PRIMARY KEY AUTO_INCREMENT,
    emp_name VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL
);

插入数据

sql 复制代码
INSERT INTO employees (emp_name, email) VALUES
('zhangsan', 'zhangsan@example.com'),
('lisi', 'lisi@example.com'),
('wangwu', 'wangwu@example.com');

答案

sql 复制代码
SELECT emp_id,
    CONCAT(UPPER(SUBSTRING(emp_name, 1, 1)), LOWER(SUBSTRING(emp_name, 2))) AS formatted_name,
    email
FROM employees;

题目10:TOP N查询

题目描述:查询成绩最高的3名学生的姓名、科目和成绩。

使用表:student_scores(同题目1)

答案

sql 复制代码
-- MySQL
SELECT student_name, subject, score
FROM student_scores
ORDER BY score DESC
LIMIT 3;

-- SQL Server
-- SELECT TOP 3 student_name, subject, score
-- FROM student_scores
-- ORDER BY score DESC;

-- PostgreSQL
-- SELECT student_name, subject, score
-- FROM student_scores
-- ORDER BY score DESC
-- LIMIT 3;

扩展练习题

题目11:分组排序与分页

题目描述:查询每个科目的前三名学生及其成绩(按成绩降序)。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT student_name, subject, score
FROM (
    SELECT student_name, subject, score,
        ROW_NUMBER() OVER (PARTITION BY subject ORDER BY score DESC) AS rn
    FROM student_scores
) AS ranked
WHERE rn <= 3;

题目12:自连接

题目描述:假设有员工表包含上级ID,查询所有员工及其直接上级的姓名。

建表语句

sql 复制代码
CREATE TABLE IF NOT EXISTS employees_with_manager (
    emp_id INT PRIMARY KEY,
    emp_name VARCHAR(50) NOT NULL,
    manager_id INT,
    FOREIGN KEY (manager_id) REFERENCES employees_with_manager(emp_id)
);

插入数据

sql 复制代码
INSERT INTO employees_with_manager (emp_id, emp_name, manager_id) VALUES
(1, 'CEO', NULL),
(2, '部门经理A', 1),
(3, '员工A1', 2),
(4, '员工A2', 2),
(5, '部门经理B', 1),
(6, '员工B1', 5);

答案

sql 复制代码
SELECT e1.emp_name AS employee_name,
       e2.emp_name AS manager_name
FROM employees_with_manager e1
LEFT JOIN employees_with_manager e2 ON e1.manager_id = e2.emp_id;
相关推荐
wuweijianlove2 小时前
算法性能的渐近与非渐近行为对比的技术4
算法
_dindong2 小时前
cf1091div2 C.Grid Covering(数论)
c++·算法
AI成长日志2 小时前
【Agentic RL】1.1 什么是Agentic RL:从传统RL到智能体学习
人工智能·学习·算法
科技小花2 小时前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸2 小时前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
D4c-lovetrain3 小时前
linux个人心得22 (mysql)
数据库·mysql
黎阳之光3 小时前
黎阳之光:视频孪生领跑者,铸就中国数字科技全球竞争力
大数据·人工智能·算法·安全·数字孪生
skywalker_113 小时前
力扣hot100-3(最长连续序列),4(移动零)
数据结构·算法·leetcode
6Hzlia3 小时前
【Hot 100 刷题计划】 LeetCode 17. 电话号码的字母组合 | C++ 回溯算法经典模板
c++·算法·leetcode
阿里小阿希3 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql