100道Java面试SQL题及答案

100道Java面试SQL题及答案

目录

  1. 基础查询与排序
  2. 聚合函数与分组
  3. 多表连接
  4. 子查询
  5. 窗口函数
  6. 日期和时间函数
  7. 字符串函数
  8. 高级查询

基础查询与排序

题目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:条件查询

题目描述:查询数学成绩大于80分的学生姓名和成绩。

使用表:student_scores(同题目1)

答案

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

题目3:去重查询

题目描述:查询所有出现过的科目名称(不重复)。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT DISTINCT subject
FROM student_scores;

题目4:模糊查询

题目描述:查询姓名以"张"开头的学生的所有成绩信息。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT *
FROM student_scores
WHERE student_name LIKE '张%';

题目5:范围查询

题目描述:查询成绩在80到90分之间的学生姓名、科目和成绩。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT student_name, subject, score
FROM student_scores
WHERE score BETWEEN 80 AND 90;

题目6:NULL值处理

题目描述:假设有一个员工表,查询没有上级的员工(即manager_id为NULL的员工)。

建表语句

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

插入数据

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

答案

sql 复制代码
SELECT emp_name
FROM employees
WHERE manager_id IS NULL;

题目7:限制查询结果

题目描述:查询前5名学生的成绩信息。

使用表:student_scores(同题目1)

答案

sql 复制代码
-- MySQL/PostgreSQL
SELECT *
FROM student_scores
LIMIT 5;

-- SQL Server
-- SELECT TOP 5 *
-- FROM student_scores;

题目8:IN子句查询

题目描述:查询语文、数学、英语三科的所有成绩信息。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT *
FROM student_scores
WHERE subject IN ('语文', '数学', '英语');

题目9:NOT IN子句查询

题目描述:查询除了数学以外的所有科目的成绩信息。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT *
FROM student_scores
WHERE subject NOT IN ('数学');

题目10:多条件排序

题目描述:查询所有学生的成绩信息,按学生姓名升序,同一学生按科目降序,同一科目按成绩升序排列。

使用表:student_scores(同题目1)

答案

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

聚合函数与分组

题目11:统计科目数量

题目描述:统计共有多少个不同的科目。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT COUNT(DISTINCT subject) AS subject_count
FROM student_scores;

题目12:计算平均成绩

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

使用表: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;

题目13:HAVING子句

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

使用表:student_scores(同题目1)

答案

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

题目14:COUNT与GROUP BY

题目描述:统计每个学生的考试次数。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT student_name, COUNT(*) AS exam_count
FROM student_scores
GROUP BY student_name;

题目15:SUM函数

题目描述:假设有一个订单表,统计每个用户的总订单金额。

建表语句

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

插入数据

sql 复制代码
INSERT INTO orders (user_id, amount, order_date) VALUES
(1, 100.50, '2023-01-01'),
(1, 200.75, '2023-01-02'),
(2, 150.00, '2023-01-03'),
(2, 300.25, '2023-01-04'),
(3, 80.00, '2023-01-05');

答案

sql 复制代码
SELECT user_id, SUM(amount) AS total_amount
FROM orders
GROUP BY user_id;

题目16:多列分组

题目描述:统计每个学生每个科目的总成绩。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT student_name, subject, SUM(score) AS total_score
FROM student_scores
GROUP BY student_name, subject;

题目17:GROUP BY与WHERE结合

题目描述:统计数学成绩大于80分的学生人数。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT COUNT(DISTINCT student_name) AS student_count
FROM student_scores
WHERE subject = '数学' AND score > 80;

题目18:DISTINCT与聚合函数

题目描述:统计共有多少个不同的学生参加了考试。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT COUNT(DISTINCT student_name) AS student_count
FROM student_scores;

题目19:GROUP BY与排序

题目描述:统计每个科目的平均成绩,并按平均成绩降序排列。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT subject, AVG(score) AS avg_score
FROM student_scores
GROUP BY subject
ORDER BY avg_score DESC;

题目20:HAVING与多条件

题目描述:找出平均成绩大于85分且考试次数大于等于2次的学生。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT student_name, AVG(score) AS avg_score, COUNT(*) AS exam_count
FROM student_scores
GROUP BY student_name
HAVING AVG(score) > 85 AND COUNT(*) >= 2;

多表连接

题目21:内连接

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

建表语句

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;

题目22:左连接

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

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

答案

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;

题目23:右连接

题目描述:查询所有学生及其所在班级名称,包括没有分配班级的学生(如果有的话)。

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

答案

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

题目24:三表连接

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

建表语句

sql 复制代码
-- student_scores表同题目1
-- students表和classes表同题目21

插入数据

sql 复制代码
-- student_scores数据同题目1
-- students数据同题目21
-- classes数据同题目21

答案

sql 复制代码
SELECT s.student_name, c.class_name, ss.score
FROM students s
INNER JOIN classes c ON s.class_id = c.class_id
INNER JOIN student_scores ss ON s.student_name = ss.student_name
WHERE ss.subject = '数学';

题目25:自连接

题目描述:查询所有员工及其直接上级的姓名。

建表语句

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

插入数据

sql 复制代码
INSERT INTO employees (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 e1
LEFT JOIN employees e2 ON e1.manager_id = e2.emp_id;

题目26:交叉连接

题目描述:查询所有学生和所有科目的笛卡尔积。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT DISTINCT s1.student_name, s2.subject
FROM student_scores s1
CROSS JOIN student_scores s2;

题目27:连接与聚合

题目描述:查询每个班级的平均数学成绩。

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

答案

sql 复制代码
SELECT c.class_name, AVG(ss.score) AS avg_math_score
FROM students s
INNER JOIN classes c ON s.class_id = c.class_id
INNER JOIN student_scores ss ON s.student_name = ss.student_name
WHERE ss.subject = '数学'
GROUP BY c.class_id, c.class_name;

题目28:连接与排序

题目描述:查询所有学生的姓名、班级名称和总分数,按总分数降序排列。

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

答案

sql 复制代码
SELECT s.student_name, c.class_name, SUM(ss.score) AS total_score
FROM students s
INNER JOIN classes c ON s.class_id = c.class_id
INNER JOIN student_scores ss ON s.student_name = ss.student_name
GROUP BY s.student_name, c.class_name
ORDER BY total_score DESC;

题目29:外连接与NULL处理

题目描述:查询所有学生的姓名、班级名称和数学成绩,包括没有数学成绩的学生(显示成绩为0)。

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

答案

sql 复制代码
SELECT s.student_name, c.class_name, COALESCE(ss.score, 0) AS math_score
FROM students s
INNER JOIN classes c ON s.class_id = c.class_id
LEFT JOIN student_scores ss ON s.student_name = ss.student_name AND ss.subject = '数学';

题目30:多条件连接

题目描述:查询2023年1月份订单金额大于100的用户ID和订单金额。

使用表:orders(同题目15)

答案

sql 复制代码
SELECT user_id, amount
FROM orders
WHERE YEAR(order_date) = 2023 AND MONTH(order_date) = 1 AND amount > 100;

子查询

题目31:单行子查询

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

使用表:student_scores(同题目1)

答案

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

题目32:多行子查询

题目描述:查询与张三所选科目相同的其他学生的成绩信息。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT *
FROM student_scores
WHERE subject IN (
    SELECT subject
    FROM student_scores
    WHERE student_name = '张三'
) AND student_name != '张三';

题目33: EXISTS子查询

题目描述:查询至少有一门成绩大于90分的学生姓名。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT DISTINCT student_name
FROM student_scores s1
WHERE EXISTS (
    SELECT 1
    FROM student_scores s2
    WHERE s1.student_name = s2.student_name AND s2.score > 90
);

题目34:NOT EXISTS子查询

题目描述:查询所有科目成绩都不低于80分的学生姓名。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT DISTINCT student_name
FROM student_scores s1
WHERE NOT EXISTS (
    SELECT 1
    FROM student_scores s2
    WHERE s1.student_name = s2.student_name AND s2.score < 80
);

题目35:关联子查询

题目描述:查询每个学生的最高成绩科目和分数。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT student_name, subject, score
FROM student_scores s1
WHERE score = (
    SELECT MAX(score)
    FROM student_scores s2
    WHERE s1.student_name = s2.student_name
);

题目36:子查询作为列

题目描述:查询每个学生的姓名和平均成绩。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT DISTINCT student_name,
    (SELECT AVG(score) FROM student_scores WHERE student_name = s.student_name) AS avg_score
FROM student_scores s;

题目37:子查询作为表

题目描述:查询平均成绩最高的学生姓名和平均成绩。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT student_name, avg_score
FROM (
    SELECT student_name, AVG(score) AS avg_score
    FROM student_scores
    GROUP BY student_name
) AS avg_scores
ORDER BY avg_score DESC
LIMIT 1;

题目38:多层子查询

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

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

答案

sql 复制代码
SELECT s.student_name, ss.score
FROM students s
INNER JOIN student_scores ss ON s.student_name = ss.student_name
WHERE ss.subject = '数学' AND ss.score > (
    SELECT AVG(ss2.score)
    FROM students s2
    INNER JOIN student_scores ss2 ON s2.student_name = ss2.student_name
    WHERE s2.class_id = s.class_id AND ss2.subject = '数学'
);

题目39:IN与子查询

题目描述:查询选修了数学和英语两门课的学生姓名。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT DISTINCT student_name
FROM student_scores
WHERE subject = '数学' AND student_name IN (
    SELECT student_name
    FROM student_scores
    WHERE subject = '英语'
);

题目40:ANY/SOME子查询

题目描述:查询成绩高于任何一个英语成绩的数学成绩记录。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT *
FROM student_scores
WHERE subject = '数学' AND score > ANY (
    SELECT score
    FROM student_scores
    WHERE subject = '英语'
);

窗口函数

题目41:ROW_NUMBER()

题目描述:为每个学生的各科成绩按成绩降序排序并编号。

使用表:student_scores(同题目1)

答案

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

题目42:RANK()

题目描述:为所有学生的数学成绩排名(允许并列)。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT student_name, subject, score,
    RANK() OVER (ORDER BY score DESC) AS math_rank
FROM student_scores
WHERE subject = '数学';

题目43:DENSE_RANK()

题目描述:为所有学生的成绩按科目进行密集排名。

使用表:student_scores(同题目1)

答案

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

题目44:SUM() OVER

题目描述:计算每个学生的累计成绩(按科目排序)。

使用表:student_scores(同题目1)

答案

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

题目45:AVG() OVER

题目描述:计算每个学生的移动平均成绩(前一项和后一项的平均)。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT student_name, subject, score,
    AVG(score) OVER (PARTITION BY student_name ORDER BY subject ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS moving_avg
FROM student_scores;

题目46:LAG()函数

题目描述:查询每个学生当前科目的成绩与前一科目的成绩之差。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT student_name, subject, score,
    LAG(score) OVER (PARTITION BY student_name ORDER BY subject) AS previous_score,
    score - LAG(score) OVER (PARTITION BY student_name ORDER BY subject) AS score_diff
FROM student_scores;

题目47:LEAD()函数

题目描述:查询每个学生当前科目的成绩与后一科目的成绩之差。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT student_name, subject, score,
    LEAD(score) OVER (PARTITION BY student_name ORDER BY subject) AS next_score,
    score - LEAD(score) OVER (PARTITION BY student_name ORDER BY subject) AS score_diff
FROM student_scores;

题目48:FIRST_VALUE()函数

题目描述:查询每个学生的各科成绩以及该学生的最高成绩。

使用表:student_scores(同题目1)

答案

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

题目49:LAST_VALUE()函数

题目描述:查询每个学生的各科成绩以及该学生的最低成绩。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT student_name, subject, score,
    LAST_VALUE(score) OVER (PARTITION BY student_name ORDER BY score DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS lowest_score
FROM student_scores;

题目50:NTILE()函数

题目描述:将所有学生的数学成绩分为3组。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT student_name, score,
    NTILE(3) OVER (ORDER BY score DESC) AS score_group
FROM student_scores
WHERE subject = '数学';

日期和时间函数

题目51:获取当前日期时间

题目描述:查询当前的日期和时间。

答案

sql 复制代码
-- MySQL
SELECT NOW() AS current_datetime;

-- SQL Server
-- SELECT GETDATE() AS current_datetime;

-- PostgreSQL
-- SELECT CURRENT_TIMESTAMP AS current_datetime;

题目52:日期格式化

题目描述:将订单日期格式化为"YYYY-MM-DD"格式。

使用表:orders(同题目15)

答案

sql 复制代码
-- MySQL
SELECT order_id, DATE_FORMAT(order_date, '%Y-%m-%d') AS formatted_date
FROM orders;

-- SQL Server
-- SELECT order_id, CONVERT(VARCHAR(10), order_date, 23) AS formatted_date
-- FROM orders;

-- PostgreSQL
-- SELECT order_id, TO_CHAR(order_date, 'YYYY-MM-DD') AS formatted_date
-- FROM orders;

题目53:年份和月份提取

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

使用表:orders(同题目15)

答案

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

题目54:日期差值计算

题目描述:计算订单的创建天数(从订单日期到当前日期的天数)。

使用表:orders(同题目15)

答案

sql 复制代码
-- MySQL
SELECT order_id, DATEDIFF(NOW(), order_date) AS days_since_order
FROM orders;

-- SQL Server
-- SELECT order_id, DATEDIFF(DAY, order_date, GETDATE()) AS days_since_order
-- FROM orders;

-- PostgreSQL
-- SELECT order_id, CURRENT_DATE - order_date AS days_since_order
-- FROM orders;

题目55:日期加减

题目描述:查询30天前创建的订单。

使用表:orders(同题目15)

答案

sql 复制代码
-- MySQL
SELECT *
FROM orders
WHERE order_date >= DATE_SUB(NOW(), INTERVAL 30 DAY);

-- SQL Server
-- SELECT *
-- FROM orders
-- WHERE order_date >= DATEADD(DAY, -30, GETDATE());

-- PostgreSQL
-- SELECT *
-- FROM orders
-- WHERE order_date >= CURRENT_DATE - INTERVAL '30 days';

题目56:获取月份的最后一天

题目描述:查询每个订单月份的最后一天。

使用表:orders(同题目15)

答案

sql 复制代码
-- MySQL
SELECT order_id, LAST_DAY(order_date) AS month_end
FROM orders;

-- SQL Server
-- SELECT order_id, EOMONTH(order_date) AS month_end
-- FROM orders;

-- PostgreSQL
-- SELECT order_id, (DATE_TRUNC('MONTH', order_date) + INTERVAL '1 MONTH' - INTERVAL '1 DAY') AS month_end
-- FROM orders;

题目57:计算年龄

题目描述:假设有一个用户表,查询每个用户的年龄。

建表语句

sql 复制代码
CREATE TABLE IF NOT EXISTS users (
    user_id INT PRIMARY KEY,
    user_name VARCHAR(50) NOT NULL,
    birth_date DATE NOT NULL
);

插入数据

sql 复制代码
INSERT INTO users (user_id, user_name, birth_date) VALUES
(1, '张三', '1990-05-15'),
(2, '李四', '1985-12-20'),
(3, '王五', '1995-08-10');

答案

sql 复制代码
-- MySQL
SELECT user_name, TIMESTAMPDIFF(YEAR, birth_date, NOW()) AS age
FROM users;

-- SQL Server
-- SELECT user_name, DATEDIFF(YEAR, birth_date, GETDATE()) - CASE WHEN MONTH(birth_date) > MONTH(GETDATE()) OR (MONTH(birth_date) = MONTH(GETDATE()) AND DAY(birth_date) > DAY(GETDATE())) THEN 1 ELSE 0 END AS age
-- FROM users;

-- PostgreSQL
-- SELECT user_name, EXTRACT(YEAR FROM AGE(birth_date)) AS age
-- FROM users;

题目58:查询本周数据

题目描述:查询本周创建的订单。

使用表:orders(同题目15)

答案

sql 复制代码
-- MySQL
SELECT *
FROM orders
WHERE YEARWEEK(order_date, 1) = YEARWEEK(NOW(), 1);

-- SQL Server
-- SELECT *
-- FROM orders
-- WHERE DATEPART(WEEK, order_date) = DATEPART(WEEK, GETDATE()) AND YEAR(order_date) = YEAR(GETDATE());

-- PostgreSQL
-- SELECT *
-- FROM orders
-- WHERE EXTRACT(WEEK FROM order_date) = EXTRACT(WEEK FROM CURRENT_DATE) AND EXTRACT(YEAR FROM order_date) = EXTRACT(YEAR FROM CURRENT_DATE);

题目59:查询本月数据

题目描述:查询本月创建的订单。

使用表:orders(同题目15)

答案

sql 复制代码
SELECT *
FROM orders
WHERE YEAR(order_date) = YEAR(NOW()) AND MONTH(order_date) = MONTH(NOW());

题目60:计算两个日期之间的工作日天数

题目描述:计算两个日期之间的工作日天数(排除周末)。

答案

sql 复制代码
-- MySQL
SELECT DATEDIFF('2023-12-31', '2023-12-01') - 2 * (WEEK('2023-12-31') - WEEK('2023-12-01')) AS workdays;

-- SQL Server
-- SELECT (DATEDIFF(DAY, '2023-12-01', '2023-12-31') + 1) - (DATEDIFF(WEEK, '2023-12-01', '2023-12-31') * 2) - CASE WHEN DATEPART(WEEKDAY, '2023-12-01') = 1 THEN 1 ELSE 0 END - CASE WHEN DATEPART(WEEKDAY, '2023-12-31') = 7 THEN 1 ELSE 0 END AS workdays;

-- PostgreSQL
-- SELECT COUNT(*) AS workdays
-- FROM generate_series('2023-12-01'::date, '2023-12-31'::date, '1 day') AS dates
-- WHERE EXTRACT(DOW FROM dates) NOT IN (0, 6);

字符串函数

题目61:字符串长度

题目描述:查询所有学生姓名的长度。

使用表:student_scores(同题目1)

答案

sql 复制代码
-- MySQL/PostgreSQL
SELECT DISTINCT student_name, LENGTH(student_name) AS name_length
FROM student_scores;

-- SQL Server
-- SELECT DISTINCT student_name, LEN(student_name) AS name_length
-- FROM student_scores;

题目62:字符串拼接

题目描述:将学生姓名和科目拼接成"姓名-科目"格式。

使用表:student_scores(同题目1)

答案

sql 复制代码
-- MySQL/PostgreSQL
SELECT CONCAT(student_name, '-', subject) AS student_subject
FROM student_scores;

-- SQL Server
-- SELECT student_name + '-' + subject AS student_subject
-- FROM student_scores;

题目63:大小写转换

题目描述:将学生姓名转换为大写。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT DISTINCT UPPER(student_name) AS upper_name
FROM student_scores;

题目64:字符串截取

题目描述:截取邮箱地址的用户名部分(@符号之前的部分)。

建表语句

sql 复制代码
CREATE TABLE IF NOT EXISTS user_emails (
    user_id INT PRIMARY KEY,
    email VARCHAR(100) NOT NULL
);

插入数据

sql 复制代码
INSERT INTO user_emails (user_id, email) VALUES
(1, 'zhangsan@example.com'),
(2, 'lisi@test.com'),
(3, 'wangwu@company.org');

答案

sql 复制代码
-- MySQL
SELECT user_id, SUBSTRING_INDEX(email, '@', 1) AS username
FROM user_emails;

-- SQL Server
-- SELECT user_id, LEFT(email, CHARINDEX('@', email) - 1) AS username
-- FROM user_emails;

-- PostgreSQL
-- SELECT user_id, SPLIT_PART(email, '@', 1) AS username
-- FROM user_emails;

题目65:字符串替换

题目描述:将邮箱地址中的"@example.com"替换为"@newcompany.com"。

使用表:user_emails(同题目64)

答案

sql 复制代码
-- MySQL/PostgreSQL
SELECT user_id, REPLACE(email, '@example.com', '@newcompany.com') AS new_email
FROM user_emails;

-- SQL Server
-- SELECT user_id, REPLACE(email, '@example.com', '@newcompany.com') AS new_email
-- FROM user_emails;

题目66:字符串查找

题目描述:查询包含"example"的邮箱地址。

使用表:user_emails(同题目64)

答案

sql 复制代码
SELECT *
FROM user_emails
WHERE email LIKE '%example%';

题目67:去除空格

题目描述:去除学生姓名前后的空格。

建表语句

sql 复制代码
CREATE TABLE IF NOT EXISTS students_with_spaces (
    student_id INT PRIMARY KEY,
    student_name VARCHAR(50) NOT NULL
);

插入数据

sql 复制代码
INSERT INTO students_with_spaces (student_id, student_name) VALUES
(1, ' 张三 '),
(2, '李四  '),
(3, '  王五');

答案

sql 复制代码
SELECT student_id, TRIM(student_name) AS trimmed_name
FROM students_with_spaces;

题目68:首字母大写

题目描述:将员工姓名的首字母大写,其余字母小写。

使用表:employees(同题目25)

答案

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

-- SQL Server
-- SELECT emp_name, UPPER(LEFT(emp_name, 1)) + LOWER(SUBSTRING(emp_name, 2, LEN(emp_name) - 1)) AS formatted_name
-- FROM employees;

-- PostgreSQL
-- SELECT emp_name, INITCAP(emp_name) AS formatted_name
-- FROM employees;

题目69:字符串分割

题目描述:假设有一个标签表,将标签字符串按逗号分割。

建表语句

sql 复制代码
CREATE TABLE IF NOT EXISTS posts (
    post_id INT PRIMARY KEY,
    post_title VARCHAR(100) NOT NULL,
    tags VARCHAR(200) NOT NULL
);

插入数据

sql 复制代码
INSERT INTO posts (post_id, post_title, tags) VALUES
(1, '文章1', 'Java,Spring,MySQL'),
(2, '文章2', 'Python,Django,PostgreSQL'),
(3, '文章3', 'JavaScript,React,Node.js');

答案

sql 复制代码
-- MySQL (8.0+)
SELECT post_id, post_title, TRIM(value) AS tag
FROM posts
CROSS JOIN JSON_TABLE(CONCAT('"', REPLACE(tags, ',', '"","'), '"'), '$[*]' COLUMNS(value VARCHAR(50) PATH ')) AS jt;

-- SQL Server
-- SELECT post_id, post_title, TRIM(value) AS tag
-- FROM posts
-- CROSS APPLY STRING_SPLIT(tags, ',');

-- PostgreSQL
-- SELECT post_id, post_title, TRIM(UNNEST(string_to_array(tags, ','))) AS tag
-- FROM posts;

题目70:字符串比较

题目描述:查询姓名按字母顺序排在"王五"之前的学生。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT DISTINCT student_name
FROM student_scores
WHERE student_name < '王五'
ORDER BY student_name;

高级查询

题目71:TOP N查询

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

使用表:student_scores(同题目1)

答案

sql 复制代码
-- MySQL/PostgreSQL
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;

题目72:分页查询

题目描述:查询第2页的学生成绩信息(每页3条)。

使用表:student_scores(同题目1)

答案

sql 复制代码
-- MySQL/PostgreSQL
SELECT *
FROM student_scores
ORDER BY id
LIMIT 3 OFFSET 3;

-- SQL Server
-- SELECT *
-- FROM student_scores
-- ORDER BY id
-- OFFSET 3 ROWS FETCH NEXT 3 ROWS ONLY;

题目73:分组排序后取TOP N

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

使用表: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;

题目74:中位数计算

题目描述:计算所有学生数学成绩的中位数。

使用表:student_scores(同题目1)

答案

sql 复制代码
-- MySQL (8.0+)
SELECT AVG(score) AS median_score
FROM (
    SELECT score, ROW_NUMBER() OVER (ORDER BY score) AS rn, COUNT(*) OVER () AS total
    FROM student_scores
    WHERE subject = '数学'
) AS scores
WHERE rn IN (FLOOR((total + 1) / 2), CEIL((total + 1) / 2));

-- PostgreSQL
-- SELECT PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY score) AS median_score
-- FROM student_scores
-- WHERE subject = '数学';

题目75:重复记录查询

题目描述:查询存在重复成绩的科目。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT subject, score, COUNT(*) AS count
FROM student_scores
GROUP BY subject, score
HAVING COUNT(*) > 1;

题目76:重复记录删除

题目描述:删除学生成绩表中的重复记录,只保留id最小的记录。

使用表:student_scores(同题目1)

答案

sql 复制代码
DELETE FROM student_scores
WHERE id NOT IN (
    SELECT MIN(id)
    FROM student_scores
    GROUP BY student_name, subject, score
);

题目77:行列转换(行转列)

题目描述:将学生成绩表转换为行表示,每个学生一行,科目作为列。

使用表:student_scores(同题目1)

答案

sql 复制代码
-- MySQL
SELECT student_name,
    MAX(CASE WHEN subject = '数学' THEN score END) AS 数学,
    MAX(CASE WHEN subject = '英语' THEN score END) AS 英语,
    MAX(CASE WHEN subject = '语文' THEN score END) AS 语文
FROM student_scores
GROUP BY student_name;

-- SQL Server
-- SELECT student_name,
--     MAX(CASE WHEN subject = '数学' THEN score END) AS 数学,
--     MAX(CASE WHEN subject = '英语' THEN score END) AS 英语,
--     MAX(CASE WHEN subject = '语文' THEN score END) AS 语文
-- FROM student_scores
-- GROUP BY student_name;

-- PostgreSQL
-- SELECT student_name,
--     MAX(CASE WHEN subject = '数学' THEN score END) AS 数学,
--     MAX(CASE WHEN subject = '英语' THEN score END) AS 英语,
--     MAX(CASE WHEN subject = '语文' THEN score END) AS 语文
-- FROM student_scores
-- GROUP BY student_name;

题目78:行列转换(列转行)

题目描述:将行转列后的学生成绩表转换回原始的列表示。

建表语句

sql 复制代码
CREATE TABLE IF NOT EXISTS student_scores_pivot (
    student_name VARCHAR(50) PRIMARY KEY,
    数学 INT NOT NULL,
    英语 INT NOT NULL,
    语文 INT NOT NULL
);

插入数据

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

答案

sql 复制代码
-- MySQL/PostgreSQL
SELECT student_name, '数学' AS subject, 数学 AS score FROM student_scores_pivot
UNION ALL
SELECT student_name, '英语' AS subject, 英语 AS score FROM student_scores_pivot
UNION ALL
SELECT student_name, '语文' AS subject, 语文 AS score FROM student_scores_pivot;

-- SQL Server
-- SELECT student_name, '数学' AS subject, 数学 AS score FROM student_scores_pivot
-- UNION ALL
-- SELECT student_name, '英语' AS subject, 英语 AS score FROM student_scores_pivot
-- UNION ALL
-- SELECT student_name, '语文' AS subject, 语文 AS score FROM student_scores_pivot;

题目79:连续日期查询

题目描述:假设有一个登录表,查询连续登录3天及以上的用户。

建表语句

sql 复制代码
CREATE TABLE IF NOT EXISTS user_logins (
    login_id INT PRIMARY KEY,
    user_id INT NOT NULL,
    login_date DATE NOT NULL
);

插入数据

sql 复制代码
INSERT INTO user_logins (login_id, user_id, login_date) VALUES
(1, 1, '2023-01-01'),
(2, 1, '2023-01-02'),
(3, 1, '2023-01-03'),
(4, 2, '2023-01-01'),
(5, 2, '2023-01-03'),
(6, 3, '2023-01-01'),
(7, 3, '2023-01-02'),
(8, 3, '2023-01-03'),
(9, 3, '2023-01-04');

答案

sql 复制代码
SELECT DISTINCT user_id
FROM (
    SELECT user_id, login_date,
        ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_date) AS rn,
        DATE_SUB(login_date, INTERVAL ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_date) DAY) AS group_date
    FROM user_logins
) AS t
GROUP BY user_id, group_date
HAVING COUNT(*) >= 3;

题目80:累计求和

题目描述:计算每个用户的累计订单金额。

使用表:orders(同题目15)

答案

sql 复制代码
SELECT user_id, order_date, amount,
    SUM(amount) OVER (PARTITION BY user_id ORDER BY order_date) AS cumulative_amount
FROM orders;

题目81:百分比计算

题目描述:计算每个订单金额占总金额的百分比。

使用表:orders(同题目15)

答案

sql 复制代码
SELECT order_id, user_id, amount,
    amount / SUM(amount) OVER () * 100 AS percentage
FROM orders;

题目82:排名变化

题目描述:假设有一个月度销售表,查询每个销售人员的本月销售额与上月销售额的变化。

建表语句

sql 复制代码
CREATE TABLE IF NOT EXISTS sales (
    sale_id INT PRIMARY KEY,
    salesperson_id INT NOT NULL,
    month INT NOT NULL,
    year INT NOT NULL,
    amount DECIMAL(10,2) NOT NULL
);

插入数据

sql 复制代码
INSERT INTO sales (sale_id, salesperson_id, month, year, amount) VALUES
(1, 1, 1, 2023, 1000.00),
(2, 1, 2, 2023, 1200.00),
(3, 1, 3, 2023, 900.00),
(4, 2, 1, 2023, 800.00),
(5, 2, 2, 2023, 850.00),
(6, 2, 3, 2023, 1100.00);

答案

sql 复制代码
SELECT salesperson_id, year, month, amount,
    LAG(amount) OVER (PARTITION BY salesperson_id ORDER BY year, month) AS previous_month_amount,
    amount - LAG(amount) OVER (PARTITION BY salesperson_id ORDER BY year, month) AS amount_change
FROM sales;

题目83:条件聚合

题目描述:统计每个学生的及格科目数和不及格科目数。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT student_name,
    SUM(CASE WHEN score >= 60 THEN 1 ELSE 0 END) AS pass_count,
    SUM(CASE WHEN score < 60 THEN 1 ELSE 0 END) AS fail_count
FROM student_scores
GROUP BY student_name;

题目84:动态条件

题目描述:根据科目动态查询每个学生的最高成绩。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT student_name,
    MAX(CASE WHEN subject = '数学' THEN score END) AS max_math,
    MAX(CASE WHEN subject = '英语' THEN score END) AS max_english,
    MAX(CASE WHEN subject = '语文' THEN score END) AS max_chinese
FROM student_scores
GROUP BY student_name;

题目85:树状结构查询

题目描述:假设有一个部门表,查询所有部门及其所有上级部门。

建表语句

sql 复制代码
CREATE TABLE IF NOT EXISTS departments (
    dept_id INT PRIMARY KEY,
    dept_name VARCHAR(50) NOT NULL,
    parent_dept_id INT
);

插入数据

sql 复制代码
INSERT INTO departments (dept_id, dept_name, parent_dept_id) VALUES
(1, '总公司', NULL),
(2, '技术部', 1),
(3, '开发部', 2),
(4, '测试部', 2),
(5, '市场部', 1),
(6, '销售部', 5);

答案

sql 复制代码
-- MySQL (8.0+)
WITH RECURSIVE department_hierarchy AS (
    SELECT dept_id, dept_name, parent_dept_id, dept_name AS full_path
    FROM departments
    WHERE parent_dept_id IS NULL
    UNION ALL
    SELECT d.dept_id, d.dept_name, d.parent_dept_id,
        CONCAT(dh.full_path, ' > ', d.dept_name) AS full_path
    FROM departments d
    INNER JOIN department_hierarchy dh ON d.parent_dept_id = dh.dept_id
)
SELECT * FROM department_hierarchy;

-- SQL Server
-- WITH department_hierarchy AS (
--     SELECT dept_id, dept_name, parent_dept_id, dept_name AS full_path
--     FROM departments
--     WHERE parent_dept_id IS NULL
--     UNION ALL
--     SELECT d.dept_id, d.dept_name, d.parent_dept_id,
--         CONCAT(dh.full_path, ' > ', d.dept_name) AS full_path
--     FROM departments d
--     INNER JOIN department_hierarchy dh ON d.parent_dept_id = dh.dept_id
-- )
-- SELECT * FROM department_hierarchy;

-- PostgreSQL
-- WITH RECURSIVE department_hierarchy AS (
--     SELECT dept_id, dept_name, parent_dept_id, dept_name AS full_path
--     FROM departments
--     WHERE parent_dept_id IS NULL
--     UNION ALL
--     SELECT d.dept_id, d.dept_name, d.parent_dept_id,
--         CONCAT(dh.full_path, ' > ', d.dept_name) AS full_path
--     FROM departments d
--     INNER JOIN department_hierarchy dh ON d.parent_dept_id = dh.dept_id
-- )
-- SELECT * FROM department_hierarchy;

题目86:TOP N分组

题目描述:查询每个用户订单金额最高的前2个订单。

使用表:orders(同题目15)

答案

sql 复制代码
SELECT user_id, order_id, amount
FROM (
    SELECT user_id, order_id, amount,
        ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY amount DESC) AS rn
    FROM orders
) AS ranked
WHERE rn <= 2;

题目87:中位数排名

题目描述:查询成绩排名在中位数位置的学生姓名和成绩。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT student_name, subject, score
FROM (
    SELECT student_name, subject, score,
        ROW_NUMBER() OVER (ORDER BY score) AS rn,
        COUNT(*) OVER () AS total
    FROM student_scores
) AS scores
WHERE rn IN (FLOOR((total + 1) / 2), CEIL((total + 1) / 2));

题目88:多条件排序

题目描述:查询所有订单,按用户ID升序,同一用户按订单金额降序,同一金额按订单日期升序排列。

使用表:orders(同题目15)

答案

sql 复制代码
SELECT *
FROM orders
ORDER BY user_id ASC, amount DESC, order_date ASC;

题目89:复杂连接查询

题目描述:假设有学生表、班级表、成绩表和课程表,查询每个学生的姓名、班级名称、课程名称和成绩。

建表语句

sql 复制代码
CREATE TABLE IF NOT EXISTS courses (
    course_id INT PRIMARY KEY,
    course_name VARCHAR(50) NOT NULL
);

-- student_scores表同题目1
-- students表和classes表同题目21

插入数据

sql 复制代码
INSERT INTO courses (course_id, course_name) VALUES
(1, '数学'),
(2, '英语'),
(3, '语文');

-- student_scores数据同题目1
-- students数据同题目21
-- classes数据同题目21

答案

sql 复制代码
SELECT s.student_name, c.class_name, co.course_name, ss.score
FROM students s
INNER JOIN classes c ON s.class_id = c.class_id
INNER JOIN student_scores ss ON s.student_name = ss.student_name
INNER JOIN courses co ON ss.subject = co.course_name;

题目90:综合查询

题目描述:查询每个班级的平均成绩,以及该班级平均成绩与全校平均成绩的差值。

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

答案

sql 复制代码
SELECT c.class_name,
    AVG(ss.score) AS class_avg,
    AVG(ss.score) - (SELECT AVG(score) FROM student_scores) AS avg_diff
FROM students s
INNER JOIN classes c ON s.class_id = c.class_id
INNER JOIN student_scores ss ON s.student_name = ss.student_name
GROUP BY c.class_id, c.class_name;

题目91:窗口函数高级应用

题目描述:计算每个学生的成绩排名,并显示排名百分比。

使用表:student_scores(同题目1)

答案

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

题目92:条件窗口函数

题目描述:计算每个学生的累计及格次数。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT student_name, subject, score,
    SUM(CASE WHEN score >= 60 THEN 1 ELSE 0 END) OVER (PARTITION BY student_name ORDER BY subject) AS cumulative_pass
FROM student_scores;

题目93:窗口函数与聚合结合

题目描述:查询每个学生的成绩与班级平均成绩的差值。

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

答案

sql 复制代码
SELECT s.student_name, c.class_name, ss.score,
    AVG(ss.score) OVER (PARTITION BY c.class_id) AS class_avg,
    ss.score - AVG(ss.score) OVER (PARTITION BY c.class_id) AS score_diff
FROM students s
INNER JOIN classes c ON s.class_id = c.class_id
INNER JOIN student_scores ss ON s.student_name = ss.student_name;

题目94:双排序窗口函数

题目描述:为每个学生的成绩按科目升序和成绩降序进行排名。

使用表:student_scores(同题目1)

答案

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

题目95:FIRST_VALUE与LAST_VALUE

题目描述:查询每个学生的第一门和最后一门科目的成绩。

使用表:student_scores(同题目1)

答案

sql 复制代码
SELECT DISTINCT student_name,
    FIRST_VALUE(score) OVER (PARTITION BY student_name ORDER BY subject) AS first_subject_score,
    LAST_VALUE(score) OVER (PARTITION BY student_name ORDER BY subject ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_subject_score
FROM student_scores;

题目96:分组内的累计和

题目描述:计算每个用户每月的累计订单金额。

使用表:orders(同题目15)

答案

sql 复制代码
SELECT user_id, YEAR(order_date) AS year, MONTH(order_date) AS month,
    SUM(amount) AS monthly_amount,
    SUM(SUM(amount)) OVER (PARTITION BY user_id ORDER BY YEAR(order_date), MONTH(order_date)) AS cumulative_amount
FROM orders
GROUP BY user_id, YEAR(order_date), MONTH(order_date);

题目97:条件统计

题目描述:统计每个班级数学成绩大于90分的学生人数。

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

答案

sql 复制代码
SELECT c.class_name,
    COUNT(DISTINCT CASE WHEN ss.subject = '数学' AND ss.score > 90 THEN s.student_id END) AS math_excellent_count
FROM students s
INNER JOIN classes c ON s.class_id = c.class_id
INNER JOIN student_scores ss ON s.student_name = ss.student_name
GROUP BY c.class_id, c.class_name;

题目98:多表关联统计

题目描述:查询每个部门的员工人数和平均工资。

建表语句

sql 复制代码
CREATE TABLE IF NOT EXISTS departments (
    dept_id INT PRIMARY KEY,
    dept_name VARCHAR(50) NOT NULL
);

CREATE TABLE IF NOT EXISTS employees (
    emp_id INT PRIMARY KEY,
    emp_name VARCHAR(50) NOT NULL,
    dept_id INT NOT NULL,
    salary DECIMAL(10,2) NOT NULL,
    FOREIGN KEY (dept_id) REFERENCES departments(dept_id)
);

插入数据

sql 复制代码
INSERT INTO departments (dept_id, dept_name) VALUES
(1, '技术部'),
(2, '市场部'),
(3, '人事部');

INSERT INTO employees (emp_id, emp_name, dept_id, salary) VALUES
(1, '张三', 1, 8000.00),
(2, '李四', 1, 9000.00),
(3, '王五', 2, 7000.00),
(4, '赵六', 2, 6500.00),
(5, '孙七', 3, 5500.00);

答案

sql 复制代码
SELECT d.dept_name, COUNT(e.emp_id) AS employee_count, AVG(e.salary) AS avg_salary
FROM departments d
LEFT JOIN employees e ON d.dept_id = e.dept_id
GROUP BY d.dept_id, d.dept_name;

题目99:动态行转列

题目描述:根据学生的科目动态生成列,并显示对应的成绩。

使用表:student_scores(同题目1)

答案

sql 复制代码
-- MySQL
SET @sql = NULL;
SELECT
    GROUP_CONCAT(DISTINCT
        CONCAT(
            'MAX(CASE WHEN subject = ''',
            subject,
            ''' THEN score END) AS ',
            CONCAT('`', subject, '`')
        )
    ) INTO @sql
FROM student_scores;

SET @sql = CONCAT('SELECT student_name, ', @sql, ' FROM student_scores GROUP BY student_name');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

-- SQL Server
-- DECLARE @sql NVARCHAR(MAX);
-- SELECT @sql = STRING_AGG(
--     CONCAT(
--         'MAX(CASE WHEN subject = ''',
--         subject,
--         ''' THEN score END) AS ',
--         QUOTENAME(subject)
--     ),
--     ', '
-- )
-- FROM (SELECT DISTINCT subject FROM student_scores) AS s;

-- SET @sql = CONCAT('SELECT student_name, ', @sql, ' FROM student_scores GROUP BY student_name');

-- EXEC sp_executesql @sql;

题目100:高级自连接

题目描述:查询所有员工及其直接下属的姓名和职位。

建表语句

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

插入数据

sql 复制代码
INSERT INTO employees (emp_id, emp_name, manager_id, position) VALUES
(1, 'CEO', NULL, '首席执行官'),
(2, '技术总监', 1, '技术总监'),
(3, '开发经理', 2, '开发经理'),
(4, '开发工程师', 3, '开发工程师'),
(5, '市场总监', 1, '市场总监'),
(6, '销售经理', 5, '销售经理');

答案

sql 复制代码
SELECT e1.emp_name AS manager_name, e1.position AS manager_position,
       e2.emp_name AS employee_name, e2.position AS employee_position
FROM employees e1
LEFT JOIN employees e2 ON e1.emp_id = e2.manager_id;

总结

以上100道SQL题涵盖了Java面试中常见的SQL知识点,包括:

  1. 基础查询与排序:SELECT、WHERE、ORDER BY、LIMIT、DISTINCT、LIKE等
  2. 聚合函数与分组:COUNT、SUM、AVG、MAX、MIN、GROUP BY、HAVING等
  3. 多表连接:INNER JOIN、LEFT JOIN、RIGHT JOIN、CROSS JOIN、自连接等
  4. 子查询:单行子查询、多行子查询、关联子查询、EXISTS/NOT EXISTS等
  5. 窗口函数:ROW_NUMBER、RANK、DENSE_RANK、SUM() OVER、LAG、LEAD等
  6. 日期和时间函数:NOW、DATE_FORMAT、YEAR、MONTH、DATEDIFF等
  7. 字符串函数:LENGTH、CONCAT、UPPER/LOWER、SUBSTRING、REPLACE等
  8. 高级查询:分页、TOP N、中位数、行列转换、树状结构等

这些题目涵盖了从基础到高级的SQL知识点,适合用于Java面试的SQL技能考察。

相关推荐
专注于大数据技术栈7 小时前
java学习--String
java·开发语言·学习
LYFlied7 小时前
【每日算法】LeetCode 20. 有效的括号
数据结构·算法·leetcode·面试
胡玉洋7 小时前
Spring Boot 项目配置文件密码加密解决方案 —— Jasypt 实战指南
java·spring boot·后端·安全·加密·配置文件·jasypt
苹果醋37 小时前
JAVA设计模式之观察者模式
java·运维·spring boot·mysql·nginx
WYiQIU7 小时前
从今天开始备战1月中旬的前端寒假实习需要准备什么?(飞书+github+源码+题库含答案)
前端·javascript·面试·职场和发展·前端框架·github·飞书
明洞日记7 小时前
【设计模式手册019】状态模式 - 管理对象状态转换
java·设计模式·状态模式
guslegend7 小时前
SpringSecurity认证原理与实战
java
JIngJaneIL7 小时前
基于java+ vue畅游游戏销售管理系统(源码+数据库+文档)
java·开发语言·数据库·vue.js·spring boot·游戏
while(1){yan}7 小时前
HTTP的加密过程
java·开发语言·网络·网络协议·http·青少年编程