SQL语句笔试题

前言

手写SQL语句是笔试、面试中常见的题型,所以本篇主要收集一些常见的SQL笔试题。

实验环境

  • MySQL 5.6 (Windows版)

第一篇

题目来源:某网站公开课(避免广告嫌疑,不具体指出)
答案来源:博主自己书写,仅供参考

表结构及数据

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for dept
-- ----------------------------
DROP TABLE IF EXISTS `dept`;
CREATE TABLE `dept`  (
  `deptno` int(2) NOT NULL,
  `dname` varchar(15) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `loc` varchar(15) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`deptno`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of dept
-- ----------------------------
INSERT INTO `dept` VALUES (10, 'ACCOUNTING', 'NewYork');
INSERT INTO `dept` VALUES (20, 'RESEARCH', 'Dallas');
INSERT INTO `dept` VALUES (30, 'SALES', 'Chicago');
INSERT INTO `dept` VALUES (40, 'OPERATIONS', 'Boston');

-- ----------------------------
-- Table structure for emp
-- ----------------------------
DROP TABLE IF EXISTS `emp`;
CREATE TABLE `emp`  (
  `empno` int(4) NOT NULL COMMENT '雇员编号',
  `ename` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `job` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `mgr` int(4) NULL DEFAULT NULL,
  `hiredate` date NULL DEFAULT NULL,
  `sal` decimal(7, 0) NULL DEFAULT NULL,
  `comm` decimal(7, 0) NULL DEFAULT NULL,
  `deptno` int(2) NULL DEFAULT NULL,
  PRIMARY KEY (`empno`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of emp
-- ----------------------------
INSERT INTO `emp` VALUES (7369, 'SMITH', 'CLERK', 7902, '1980-12-17', 800, NULL, 20);
INSERT INTO `emp` VALUES (7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 1600, 300, 30);
INSERT INTO `emp` VALUES (7521, 'WARD', 'SALESMAN', 7698, '1981-02-22', 1250, 500, 30);
INSERT INTO `emp` VALUES (7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 2975, NULL, 20);
INSERT INTO `emp` VALUES (7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28', 1250, 1400, 30);
INSERT INTO `emp` VALUES (7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01', 2850, NULL, 30);
INSERT INTO `emp` VALUES (7782, 'CLARK', 'MANAGER', 7839, '1981-06-09', 2450, NULL, 10);
INSERT INTO `emp` VALUES (7788, 'SCOTT', 'ANALYST', 7566, '1987-07-13', 3000, NULL, 20);
INSERT INTO `emp` VALUES (7839, 'KING', 'PRESIDENT', NULL, '1981-11-17', 5000, NULL, 10);
INSERT INTO `emp` VALUES (7844, 'TURNER', 'SALESMAN', 7698, '1981-09-08', 1500, 0, 30);
INSERT INTO `emp` VALUES (7876, 'ADAMS', 'CLERK', 7788, '1987-07-13', 1100, NULL, 20);
INSERT INTO `emp` VALUES (7900, 'JAMES', 'CLERK', 7698, '1981-12-03', 950, NULL, 30);
INSERT INTO `emp` VALUES (7902, 'FORD', 'ANALYST', 7566, '1981-12-03', 3000, NULL, 20);
INSERT INTO `emp` VALUES (7934, 'MILLER', 'CLERK', 7782, '1982-01-23', 1300, NULL, 10);

-- ----------------------------
-- Table structure for salgrade
-- ----------------------------
DROP TABLE IF EXISTS `salgrade`;
CREATE TABLE `salgrade`  (
  `grade` int(7) NULL DEFAULT NULL,
  `losal` int(7) NULL DEFAULT NULL,
  `hisal` int(7) NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of salgrade
-- ----------------------------
INSERT INTO `salgrade` VALUES (1, 700, 1200);
INSERT INTO `salgrade` VALUES (2, 1201, 1400);
INSERT INTO `salgrade` VALUES (3, 1401, 2000);
INSERT INTO `salgrade` VALUES (4, 2001, 3000);
INSERT INTO `salgrade` VALUES (5, 3001, 9999);

SET FOREIGN_KEY_CHECKS = 1;

部门平均薪水的等级

先求部门的平均薪水,再求这个薪水所处的等级

SELECT t.deptno, t.avgsal, s.`grade` FROM salgrade s 
 JOIN (
	 SELECT e.`deptno`, AVG(e.`sal`) AS avgsal FROM emp e 
	 GROUP BY e.`deptno`
) t ON t.avgsal >= s.`losal` AND t.avgsal <= s.`hisal`

执行结果

+--------+-----------+-------+
| deptno | avgsal    | grade |
+--------+-----------+-------+
|     10 | 2916.6667 |     4 |
|     20 | 2175.0000 |     4 |
|     30 | 1566.6667 |     3 |
+--------+-----------+-------+

部门薪水等级的平均值

先求每个部门每个员工的薪水等级,再求薪水等级的平均值

SELECT e.`deptno`,  AVG(s.`grade`) AS avggrade 
FROM emp e
 LEFT JOIN salgrade s ON e.`sal` >= s.`losal` AND e.`sal` <= s.`hisal`
GROUP BY e.`deptno`

执行结果

+--------+----------+
| deptno | avggrade |
+--------+----------+
|     10 |   3.6667 |
|     20 |   2.8000 |
|     30 |   2.5000 |
+--------+----------+

哪些人是经理

emp表中mgr字段中所有的编号就是经理

SELECT DISTINCT m.`empno`, m.`ename`
FROM emp e  
JOIN emp m ON e.`mgr` = m.`empno`

执行结果

+-------+-------+
| empno | ename |
+-------+-------+
|  7902 | FORD  |
|  7698 | BLAKE |
|  7839 | KING  |
|  7566 | JONES |
|  7788 | SCOTT |
|  7782 | CLARK |
+-------+-------+

不用组函数求最高薪水

利用ALL关键字结合子查询,实现max函数的效果

SELECT DISTINCT e.`sal` FROM emp e
WHERE e.`sal` >= ALL (SELECT e2.`sal` FROM emp e2)

执行结果

+------+
| sal  |
+------+
| 5000 |
+------+

平均薪水最高的部门编号与名称

先求每个部门的平均薪水,再取平均薪水最高的部门信息

SELECT d.`deptno`, d.`dname` FROM dept d
JOIN  (
	SELECT t.deptno, MAX(t.avgsal) FROM (
		SELECT e.`deptno`, AVG(e.`sal`) AS avgsal FROM emp e
		GROUP BY e.`deptno`
	) t 
) o ON d.`deptno` = o.deptno

执行结果

+--------+------------+
| deptno | dname      |
+--------+------------+
|     10 | ACCOUNTING |
+--------+------------+

平均薪水的等级最低的部门的部门名称

先求每个部门平均薪水的等级,再求等级最低的部门名称

SELECT d.`dname` FROM dept d 
JOIN (
	SELECT t.deptno, MIN(s.`grade`) FROM (
		SELECT e.`deptno`, AVG(e.`sal`) AS avgsal FROM  emp e
		GROUP BY e.`deptno`
	) t 
	LEFT JOIN salgrade s ON t.avgsal >= s.`losal` AND t.avgsal <= s.`hisal`
) o ON d.`deptno` = o.deptno

执行结果

+-------+
| dname |
+-------+
| SALES |
+-------+

比普通员工的最高薪水还要高的经理人名称

普通员工是指emp表中mgr列没有出现过的员工,先找出它们的最高薪水,再查询比这个最高薪水还高的经理人名称

SELECT e.`ename` FROM emp e 
WHERE e.`empno` IN (SELECT j.`mgr` FROM emp  j WHERE j.`mgr` IS NOT NULL)
AND e.`sal` > (
	SELECT MAX(e.`sal`) FROM emp e 
	WHERE e.`empno` NOT IN (SELECT i.`mgr` FROM emp i WHERE i.`mgr` IS NOT NULL)
)

执行结果

+-------+
| ename |
+-------+
| FORD  |
| BLAKE |
| KING  |
| JONES |
| SCOTT |
| CLARK |
+-------+

第二篇

题目来源:同上
答案来源:同上

表结构及数据

CREATE TABLE S (
	SNO INT PRIMARY KEY,
	SNAME VARCHAR(10)
);

CREATE TABLE C(
	CNO INT PRIMARY KEY, 
	CNAME VARCHAR(10),
	CTEACHER VARCHAR(10)
);

CREATE TABLE SC(
	SNO INT,
	CNO INT,
	SCGRADE INT
);

INSERT INTO s VALUES (1, 'zhangsan');
INSERT INTO s VALUES (2, 'lisi');
INSERT INTO s VALUES (3, 'wangwu');

INSERT INTO c VALUES (1, '数学', 'liming');
INSERT INTO c VALUES (2, '语文', 'liming');
INSERT INTO c VALUES (3, '历史', 'xueyou');
INSERT INTO c VALUES (4, '物理', 'guorong');
INSERT INTO c VALUES (5, '化学', 'liming');

INSERT INTO sc VALUES (1, 1, 59);
INSERT INTO sc VALUES (1, 2, 70);
INSERT INTO sc VALUES (2, 1, 30);
INSERT INTO sc VALUES (1, 3, 16);
INSERT INTO sc VALUES (2, 3, 61);
INSERT INTO sc VALUES (3, 1, 17);
INSERT INTO sc VALUES (3, 2, 100);
INSERT INTO sc VALUES (3, 5, 25);
INSERT INTO sc VALUES (1, 4, 99);

没选过"liming"老师的课的所有学生的名字

先找出选了liming老师课的所有学生,再用NOT IN关键字

SELECT s.sname FROM s WHERE s.sno NOT IN (
	SELECT DISTINCT s.sno FROM s
	 LEFT JOIN sc ON s.sno = sc.sno
	 LEFT JOIN c ON sc.cno = c.cno
	WHERE c.cteacher = 'liming'
) 

执行结果

Empty set (0.00 sec)

2门以上(包括2门)不及格学生姓名及平均成绩

先找出2门不及格的学生的学号,再进行其他条件的判断

SELECT s.sname, AVG(sc.scgrade) AS avgscgrade FROM s 
JOIN (
	SELECT sc.sno FROM sc
	WHERE sc.scgrade < 60
	GROUP BY sc.sno
	HAVING COUNT(*) > 1
) t ON s.sno = t.sno
JOIN sc ON sc.sno = s.sno
GROUP BY sc.sno

执行结果

+----------+------------+
| sname    | avgscgrade |
+----------+------------+
| zhangsan |    61.0000 |
| wangwu   |    47.3333 |
+----------+------------+

既学过1号课程又学过2号课程的学生的姓名

SELECT DISTINCT s.sname FROM sc
 LEFT JOIN s ON sc.sno = s.sno
WHERE sc.sno IN (SELECT sc.sno FROM sc WHERE sc.cno = 1)
 AND sc.sno IN (SELECT sc.sno FROM sc WHERE sc.cno = 2)

执行结果

+----------+
| sname    |
+----------+
| zhangsan |
| wangwu   |
+----------+
发布了52 篇原创文章 · 获赞 107 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Baisitao_/article/details/104099253