> 技术文档 > MYSQL数据库SQL语句基础练习—— 40道经典练习题详解(含练习数据库)

MYSQL数据库SQL语句基础练习—— 40道经典练习题详解(含练习数据库)


SQL基础练习(基础版)- 40道经典练习题详解

前言

SQL(Structured Query Language)是数据库操作的标准语言,掌握SQL基础语法对于数据库开发和管理至关重要。本文整理了40道SQL基础练习题,涵盖了SELECT查询、条件筛选、排序、分组、函数使用等核心知识点。

数据库表结构

在开始练习之前,我们先创建测试数据库表结构:

部门表(dept)

-- ------------------------------ 创建部门表-- ----------------------------DROP TABLE IF EXISTS dept;CREATE TABLE dept ( DEPTNO int(11) NOT NULL COMMENT \'部门编号\', DNAME varchar(20) NOT NULL COMMENT \'部门名称\', LOC varchar(20) COMMENT \'部门所在的位置\', PRIMARY KEY (DEPTNO) ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COMMENT = \'部门表\';

员工表(emp)

-- ------------------------------ 创建员工表-- ----------------------------DROP TABLE IF EXISTS emp;CREATE TABLE emp ( EMPNO int(11) NOT NULL COMMENT \'雇员的编号\', ENAME varchar(50) NOT NULL COMMENT \'雇员的姓名\',JOBvarchar(50) NOT NULL COMMENT \'职位\', MGR int(11) NULL DEFAULT NULL COMMENT \'雇员对应的领导编号\', HIREDATE date NULL DEFAULT NULL COMMENT \'雇员的雇佣日期\', SAL decimal(7, 2) NULL DEFAULT NULL COMMENT \'基本工资\', COMM decimal(7, 2) NULL DEFAULT NULL COMMENT \'奖金,佣金\', DEPTNO int(11) NULL DEFAULT NULL COMMENT \'雇员所在的部门编号\', PRIMARY KEY (EMPNO), CONSTRAINT FK_EMP_DEPTNO FOREIGN KEY (DEPTNO) REFERENCES dept (DEPTNO) ON DELETE RESTRICT ON UPDATE RESTRICT) ENGINE = InnoDB CHARACTER SET = utf8mb4 COMMENT = \'员工表\';

工资等级表(salgrade)

-- ------------------------------ 工资等级表-- ----------------------------DROP TABLE IF EXISTS salgrade;CREATE TABLE salgrade ( GRADE int(11) NOT NULL COMMENT \'工资的等级 主键\', LOSAL decimal(7, 2) NOT NULL COMMENT \'此等级的最低工资\', HISAL decimal(7, 2) NOT NULL COMMENT \'此等级的最高工资\', PRIMARY KEY (GRADE)) ENGINE = InnoDB CHARACTER SET = utf8mb4 COMMENT = \'工资等级表\' ;

测试数据

部门表数据

-- ------------------------------ 部门表插入数据-- ----------------------------INSERT INTO DEPT VALUES (10, \'财务部\', \'武汉\');INSERT INTO DEPT VALUES (20, \'研发部\', \'武汉\');INSERT INTO DEPT VALUES (30, \'销售部\', \'深圳\');INSERT INTO DEPT VALUES (40, \'业务部\', \'上海\');

员工表数据

-- ------------------------------ 员工表插入数据-- ----------------------------INSERT INTO EMP values (7369, \'SMITH\', \'CLERK\', 7902, \'1980-12-17\', 800.00, null, 20);INSERT INTO EMP values (7499, \'ALLEN\', \'SALESMAN\', 7698, \'1981-02-20\', 1600.00, 300.00, 30);INSERT INTO EMP values (7521, \'WARD\', \'SALESMAN\', 7698, \'1981-02-22\', 1250.00, 500.00, 30);INSERT INTO EMP values (7566, \'JONES\', \'MANAGER\', 7839, \'1981-04-02\', 2975.00, null, 20);INSERT INTO EMP values (7654, \'MARTIN\', \'SALESMAN\', 7698, \'1981-09-28\', 1250.00, 1400.00, 30);INSERT INTO EMP values (7698, \'BLAKE\', \'MANAGER\', 7839, \'1981-05-01\', 2850.00, null, 30);INSERT INTO EMP values (7782, \'CLARK\', \'MANAGER\', 7839, \'1981-06-09\', 2450.00, null, 10);INSERT INTO EMP values (7788, \'SCOTT\', \'ANALYST\', 7566, \'1987-04-19\', 3000.00, null, 20);INSERT INTO EMP values (7839, \'KING\', \'PRESIDENT\', null, \'1981-11-17\', 5000.00, null, 10);INSERT INTO EMP values (7844, \'TURNER\', \'SALESMAN\', 7698, \'1981-09-08\', 1500.00, 0.00, 30);INSERT INTO EMP values (7876, \'ADAMS\', \'CLERK\', 7788, \'1987-05-23\', 1100.00, null, 20);INSERT INTO EMP values (7900, \'JAMES\', \'CLERK\', 7698, \'1981-12-03\', 950.00, null, 30);INSERT INTO EMP values (7902, \'FORD\', \'ANALYST\', 7566, \'1981-12-03\', 3000.00, null, 20);INSERT INTO EMP values (7934, \'MILLER\', \'CLERK\', 7782, \'1982-01-23\', 1300.00, null, 10);

工资等级表数据

-- ------------------------------ 工资等级表插入数据-- ----------------------------INSERT INTO SALGRADE (GRADE, LOSAL, HISAL) values (1, 700, 1200);INSERT INTO SALGRADE (GRADE, LOSAL, HISAL) values (2, 1201, 1400);INSERT INTO SALGRADE (GRADE, LOSAL, HISAL) values (3, 1401, 2000);INSERT INTO SALGRADE (GRADE, LOSAL, HISAL) values (4, 2001, 3000);INSERT INTO SALGRADE (GRADE, LOSAL, HISAL) values (5, 3001, 9999);

表关系说明

  • emp表:员工信息表,包含员工的基本信息
  • dept表:部门信息表,包含部门的基本信息
  • salgrade表:工资等级表,用于工资等级划分
  • 关联关系:emp表的DEPTNO字段关联dept表的DEPTNO字段

练习题目与解析

1. 时间函数应用

题目:找出早于38年前受雇的员工

SELECT * FROM emp WHERE TIMESTAMPDIFF(YEAR, hiredate, NOW()) > 38;

解析:

  • TIMESTAMPDIFF(YEAR, hiredate, NOW()):计算雇佣日期到现在的年数差
  • NOW():获取当前日期时间
  • 注意:原题写的是12年,但题目要求是38年前,所以应该是 > 38

2. 字符串函数 - 首字母大写

题目:以首字母大写其它字母小写的方式显示所有员工的姓名

SELECT CONCAT(UPPER(SUBSTRING(ENAME, 1, 1)), LOWER(SUBSTRING(ENAME, 2))) AS name FROM emp;

解析:

  • SUBSTRING(ENAME, 1, 1):提取姓名的第一个字符
  • SUBSTRING(ENAME, 2):提取姓名从第二个字符开始的所有字符
  • UPPER():转换为大写
  • LOWER():转换为小写
  • CONCAT():连接字符串

3. 字符串匹配 - 排除特定字符

题目:显示不带有\"R\"的员工的姓名

SELECT * FROM emp WHERE ename NOT LIKE \'%R%\';

解析:

  • NOT LIKE \'%R%\':排除姓名中包含字母R的员工
  • %:通配符,表示任意字符
  • 注意:原题 NOT LIKE \'R\' 只排除以R开头的,应该用 NOT LIKE \'%R%\'

4. 字符串替换函数

题目:显示所有员工的姓名,用a替换所有\"A\"

SELECT REPLACE(ename, \'A\', \'a\') AS mname FROM emp;

解析:

  • REPLACE(ename, \'A\', \'a\'):将姓名中的大写A替换为小写a
  • 这是字符串替换的标准用法

5. 表连接与排序

题目:显示员工的详细资料,按姓名排序

SELECT e.*, dt.dname, dt.loc FROM emp e LEFT JOIN dept dt ON e.DEPTNO = dt.DEPTNO ORDER BY ename;

解析:

  • LEFT JOIN:左连接,保留左表(emp)的所有记录
  • e.*:选择emp表的所有字段
  • ORDER BY ename:按姓名升序排序

6. 日期排序

题目:显示员工的姓名和受雇日期,根据其服务年限,将最老的员工排在最前面

SELECT ENAME, HIREDATE FROM emp ORDER BY HIREDATE;

解析:

  • ORDER BY HIREDATE:按雇佣日期升序排序,最早的日期(最老的员工)排在前面

7. 多字段排序

题目:显示所有员工的姓名、工作和薪金,按工作的降序排序,若工作相同则按薪金排序

SELECT ENAME, JOB, SAL FROM emp ORDER BY JOB DESC, SAL ASC;

解析:

  • ORDER BY JOB DESC, SAL ASC:先按工作降序,再按薪金升序
  • 多字段排序时,从左到右依次排序

8. 日期提取与排序

题目:显示所有员工的姓名、加入公司的年份和月份,按受雇日期所在月排序,若月份相同则将最早年份的员工排在最前面

SELECT ename, EXTRACT(YEAR FROM hiredate) AS, EXTRACT(MONTH FROM hiredate) ASFROM emp ORDER BYASC,ASC;

解析:

  • EXTRACT(YEAR FROM hiredate):提取年份
  • EXTRACT(MONTH FROM hiredate):提取月份
  • 注意:题目要求按月份排序,若月份相同则按年份排序,所以是 ORDER BY 月 ASC, 年 ASC

9. 月份筛选

题目:找出在(任何年份的)2月受聘的所有员工

SELECT * FROM emp WHERE MONTH(hiredate) = 2;

解析:

  • MONTH(hiredate):提取日期的月份部分
  • 这样可以筛选出所有2月份入职的员工,不限年份

10. 日期差值计算

题目:对于每个员工,显示其加入公司的天数

-- 方法1:使用DATEDIFFSELECT ename, hiredate, DATEDIFF(CURDATE(), hiredate) AS days FROM emp;-- 方法2:使用TIMESTAMPDIFFSELECT ename, TIMESTAMPDIFF(DAY, hiredate, NOW()) AS days FROM emp;

解析:

  • DATEDIFF(CURDATE(), hiredate):计算当前日期与雇佣日期的天数差
  • TIMESTAMPDIFF(DAY, hiredate, NOW()):同样计算天数差,但使用不同的函数

11. 模糊查询

题目:显示姓名字段的任何位置包含\"A\"的所有员工的姓名

SELECT * FROM emp WHERE ename LIKE \'%A%\';

解析:

  • LIKE \'%A%\':匹配姓名中包含字母A的所有员工
  • %:表示任意数量的任意字符

12. 基本字段选择

题目:检索emp表中的员工姓名、月收入及部门编号

SELECT ename, sal, deptno FROM emp;

解析:

  • 基本的字段选择,选择指定的三个字段

13. 去重查询

题目:检索emp表中的部门编号及工种,并去掉重复行

SELECT DISTINCT deptno, job FROM emp;

解析:

  • DISTINCT:去除重复的行
  • 只显示唯一的部门编号和工种组合

14. 计算字段与空值处理

题目:检索emp表中的员工姓名及全年收入

SELECT ename, (sal * 12 + IFNULL(comm, 0)) AS total_income FROM emp;

解析:

  • sal * 12:月薪乘以12得到年薪
  • IFNULL(comm, 0):如果佣金为空,则用0代替
  • 全年收入 = 年薪 + 佣金

15. 字符串连接

题目:检索emp表,用\"is a\"这个字符串来连接员工姓名和工种两个字段

SELECT CONCAT_WS(\' is a \', ENAME, JOB) AS said FROM emp;

解析:

  • CONCAT_WS(\' is a \', ENAME, JOB):用\"is a\"作为分隔符连接姓名和工种
  • 结果格式:如\"SMITH is a CLERK\"

16. 数值比较

题目:检索月收入大于2000的员工姓名及月收入

SELECT ename, sal FROM emp WHERE sal > 2000;

解析:

  • 使用 > 运算符进行数值比较

17. 范围查询

题目:检索月收入在1000元到2000元的员工姓名、月收入及雇佣时间

SELECT ename, sal, hiredate FROM emp WHERE sal BETWEEN 1000 AND 2000;

解析:

  • BETWEEN 1000 AND 2000:包含边界值的范围查询
  • 等价于 sal >= 1000 AND sal <= 2000

18. 前缀匹配

题目:检索以S开头的员工姓名及月收入

SELECT ename, sal FROM emp WHERE ename LIKE \'S%\';

解析:

  • LIKE \'S%\':匹配以S开头的姓名
  • %:表示任意数量的任意字符

19. 字符位置查询

题目:检索员工姓名中的第三个字符是A的员工姓名及月收入

SELECT ename, sal FROM emp WHERE SUBSTRING(ename, 3, 1) = \'A\';

解析:

  • SUBSTRING(ename, 3, 1):从姓名的第3个位置开始,提取1个字符
  • 检查提取的字符是否等于’A’

20. 逻辑运算符

题目:检索emp表中月收入是800的或是1250的员工姓名及部门编号

SELECT ename, deptno FROM emp WHERE sal = 800 OR sal = 1250;

解析:

  • 使用 OR 逻辑运算符
  • 注意:原题写的是 sal = 800 or 1250,这是错误的语法,应该是 sal = 800 OR sal = 1250

21. 多条件查询

题目:显示在部门20中岗位CLERK的所有雇员信息

SELECT * FROM emp WHERE deptno = 20 AND job = \'CLERK\';

解析:

  • 使用 AND 逻辑运算符组合多个条件
  • 必须同时满足两个条件

22. 空值查询

题目:检索emp表中有提成的员工姓名、月收入及提成

SELECT ename, sal, comm FROM emp WHERE comm IS NOT NULL;

解析:

  • IS NOT NULL:查询非空值
  • 注意:不能用 comm != NULL,必须用 IS NOT NULL

23. 条件筛选

题目:查询职(job)为’PRESIDENT’的员工的工资

SELECT sal FROM emp WHERE job = \'PRESIDENT\';

解析:

  • 简单的条件筛选,只返回满足条件的工资字段

24. 空值与零值查询

题目:查询佣金为0或为null的员工的信息

SELECT * FROM emp WHERE comm IS NULL OR comm = 0;

解析:

  • comm IS NULL:佣金为空
  • comm = 0:佣金为0
  • 使用 OR 连接两个条件

25. 日期范围查询

题目:查询入职日期在1981-5-1到1981-12-31之间的所有员工的信息

SELECT * FROM emp WHERE hiredate BETWEEN \'1981-5-1\' AND \'1981-12-31\';

解析:

  • BETWEEN:包含边界值的范围查询
  • 日期格式:‘YYYY-M-D’

26. 字符串长度函数

题目:查询所有名字长度为4的员工的员工的编号,姓名

SELECT empno, ename FROM emp WHERE LENGTH(ename) = 4;

解析:

  • LENGTH(ename):计算姓名的字符长度
  • 筛选长度为4的姓名

27. 复杂条件查询

题目:显示10号部门所有经理和20号部门的所有员工

SELECT * FROM emp WHERE (deptno = 10 AND job = \'MANAGER\') OR deptno = 20;

解析:

  • 使用括号确保逻辑运算的优先级
  • (deptno = 10 AND job = \'MANAGER\'):10号部门的经理
  • OR deptno = 20:或者20号部门的所有员工

28. 复杂字符串匹配

题目:显示姓名没有’L’字的员工的详细信息或含有’SM’字的员工信息

SELECT * FROM emp WHERE ename NOT LIKE \'%L%\' OR ename LIKE \'%SM%\';

解析:

  • ename NOT LIKE \'%L%\':姓名中不包含L
  • OR ename LIKE \'%SM%\':或者姓名中包含SM
  • 注意:这里用的是OR,所以包含SM的员工即使有L也会被显示

29. 职位筛选

题目:显示各个部门经理的工资

SELECT ename, sal FROM emp WHERE job = \'MANAGER\';

解析:

  • 筛选职位为MANAGER的员工

30. 数值比较

题目:显示佣金收入比工资高的员工的详细信息

SELECT * FROM emp WHERE comm > sal;

解析:

  • 比较佣金和工资的大小
  • 注意:如果佣金为NULL,比较结果会是NULL,不会返回该记录

31. 日期降序排序

题目:按照入职日期由新到旧排列员工信息

SELECT * FROM emp ORDER BY hiredate DESC;

解析:

  • ORDER BY hiredate DESC:按雇佣日期降序排序
  • 最新的日期排在前面

32. 日期比较

题目:求1981年下半年入职的员工

SELECT * FROM emp WHERE hiredate >= \'1981-07-01\' AND hiredate <= \'1981-12-31\';

解析:

  • 筛选1981年7月1日到12月31日之间入职的员工
  • 下半年通常指7月到12月
  • 使用 BETWEEN 也可以:WHERE hiredate BETWEEN \'1981-07-01\' AND \'1981-12-31\'

33. 月份匹配

题目:把hiredate列看做是员工的生日,求本月过生日的员工

SELECT * FROM emp WHERE MONTH(hiredate) = MONTH(CURDATE());

解析:

  • MONTH(hiredate):提取雇佣日期的月份
  • MONTH(CURDATE()):提取当前日期的月份
  • 比较两个月份是否相等

34. 年份筛选

题目:求1982年入职的员工

SELECT * FROM emp WHERE YEAR(hiredate) = 1982;

解析:

  • YEAR(hiredate):提取雇佣日期的年份
  • 筛选1982年入职的员工

35. 分组聚合 - 平均值

题目:查询各个部门的平均工资

SELECT deptno, AVG(sal) AS avg_sal FROM emp GROUP BY deptno;

解析:

  • GROUP BY deptno:按部门分组
  • AVG(sal):计算每个部门的平均工资
  • 聚合函数与GROUP BY配合使用

36. 分组聚合 - 最小值

题目:显示各种职位的最低工资

SELECT job, MIN(sal) AS min_sal FROM emp GROUP BY job;

解析:

  • GROUP BY job:按职位分组
  • MIN(sal):计算每个职位的最低工资

37. 分组聚合 - 最大值

题目:查询每个部门的最高工资

SELECT deptno, MAX(sal) AS max_sal FROM emp GROUP BY deptno;

解析:

  • GROUP BY deptno:按部门分组
  • MAX(sal):计算每个部门的最高工资

38. 多字段分组

题目:查询每个部门,每个职位的最高工资

SELECT deptno, job, MAX(sal) AS max_sal FROM emp GROUP BY deptno, job;

解析:

  • GROUP BY deptno, job:按部门和职位两个字段分组
  • 显示每个部门-职位组合的最高工资

39. 分组后过滤 - HAVING

题目:列出各种工作的最低薪金,并使最低薪金大于1500(分组和过滤)

SELECT job, MIN(sal) AS min_sal FROM emp GROUP BY job HAVING MIN(sal) > 1500;

解析:

  • GROUP BY job:按职位分组
  • HAVING MIN(sal) > 1500:对分组后的结果进行过滤
  • HAVING:用于对聚合结果进行条件筛选

40. 分组聚合总结

题目:列出各种类别工作(分组)的最低工资

SELECT job, MIN(sal) AS min_sal FROM emp GROUP BY job;

解析:

  • 基本的按职位分组查询最低工资
  • 与第36题相同,展示了GROUP BY的基本用法

重要知识点总结

1. 字符串函数

  • SUBSTRING(str, pos, len):提取子字符串
  • UPPER(str) / LOWER(str):大小写转换
  • CONCAT(str1, str2, ...):字符串连接
  • CONCAT_WS(separator, str1, str2, ...):用分隔符连接
  • REPLACE(str, from_str, to_str):字符串替换
  • LENGTH(str):字符串长度

2. 日期函数

  • NOW() / CURDATE():当前日期时间/日期
  • YEAR(date) / MONTH(date) / DAY(date):提取年月日
  • EXTRACT(YEAR FROM date):提取年份
  • DATEDIFF(date1, date2):计算日期差
  • TIMESTAMPDIFF(unit, datetime1, datetime2):计算时间差

3. 聚合函数

  • AVG(column):平均值
  • MIN(column):最小值
  • MAX(column):最大值
  • COUNT(column):计数
  • SUM(column):求和

4. 条件查询

  • WHERE:基本条件筛选
  • HAVING:分组后条件筛选
  • LIKE / NOT LIKE:模式匹配
  • IS NULL / IS NOT NULL:空值判断
  • BETWEEN ... AND ...:范围查询

5. 排序与分组

  • ORDER BY:排序(ASC升序,DESC降序)
  • GROUP BY:分组
  • DISTINCT:去重

6. 表连接

  • LEFT JOIN:左连接
  • INNER JOIN:内连接
  • RIGHT JOIN:右连接

7. 逻辑运算符

  • AND:与
  • OR:或
  • NOT:非

常见错误与注意事项

  1. 空值处理:使用 IS NULL 而不是 = NULL
  2. 字符串匹配:注意 LIKE= 的区别
  3. 日期格式:确保日期格式正确
  4. 聚合函数:聚合函数不能直接用在WHERE子句中
  5. GROUP BY:SELECT中的非聚合字段必须出现在GROUP BY中
  6. HAVING vs WHERE:WHERE用于行级过滤,HAVING用于分组后过滤

完整SQL脚本

为了方便读者练习,这里提供完整的SQL脚本:

-- =============================================-- SQL基础练习完整脚本-- =============================================-- 创建部门表DROP TABLE IF EXISTS dept;CREATE TABLE dept ( DEPTNO int(11) NOT NULL COMMENT \'部门编号\', DNAME varchar(20) NOT NULL COMMENT \'部门名称\', LOC varchar(20) COMMENT \'部门所在的位置\', PRIMARY KEY (DEPTNO) ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COMMENT = \'部门表\';-- 创建员工表DROP TABLE IF EXISTS emp;CREATE TABLE emp ( EMPNO int(11) NOT NULL COMMENT \'雇员的编号\', ENAME varchar(50) NOT NULL COMMENT \'雇员的姓名\',JOBvarchar(50) NOT NULL COMMENT \'职位\', MGR int(11) NULL DEFAULT NULL COMMENT \'雇员对应的领导编号\', HIREDATE date NULL DEFAULT NULL COMMENT \'雇员的雇佣日期\', SAL decimal(7, 2) NULL DEFAULT NULL COMMENT \'基本工资\', COMM decimal(7, 2) NULL DEFAULT NULL COMMENT \'奖金,佣金\', DEPTNO int(11) NULL DEFAULT NULL COMMENT \'雇员所在的部门编号\', PRIMARY KEY (EMPNO), CONSTRAINT FK_EMP_DEPTNO FOREIGN KEY (DEPTNO) REFERENCES dept (DEPTNO) ON DELETE RESTRICT ON UPDATE RESTRICT) ENGINE = InnoDB CHARACTER SET = utf8mb4 COMMENT = \'员工表\';-- 工资等级表DROP TABLE IF EXISTS salgrade;CREATE TABLE salgrade ( GRADE int(11) NOT NULL COMMENT \'工资的等级 主键\', LOSAL decimal(7, 2) NOT NULL COMMENT \'此等级的最低工资\', HISAL decimal(7, 2) NOT NULL COMMENT \'此等级的最高工资\', PRIMARY KEY (GRADE)) ENGINE = InnoDB CHARACTER SET = utf8mb4 COMMENT = \'工资等级表\' ;-- 插入部门数据INSERT INTO DEPT VALUES (10, \'财务部\', \'武汉\');INSERT INTO DEPT VALUES (20, \'研发部\', \'武汉\');INSERT INTO DEPT VALUES (30, \'销售部\', \'深圳\');INSERT INTO DEPT VALUES (40, \'业务部\', \'上海\');-- 插入员工数据INSERT INTO EMP values (7369, \'SMITH\', \'CLERK\', 7902, \'1980-12-17\', 800.00, null, 20);INSERT INTO EMP values (7499, \'ALLEN\', \'SALESMAN\', 7698, \'1981-02-20\', 1600.00, 300.00, 30);INSERT INTO EMP values (7521, \'WARD\', \'SALESMAN\', 7698, \'1981-02-22\', 1250.00, 500.00, 30);INSERT INTO EMP values (7566, \'JONES\', \'MANAGER\', 7839, \'1981-04-02\', 2975.00, null, 20);INSERT INTO EMP values (7654, \'MARTIN\', \'SALESMAN\', 7698, \'1981-09-28\', 1250.00, 1400.00, 30);INSERT INTO EMP values (7698, \'BLAKE\', \'MANAGER\', 7839, \'1981-05-01\', 2850.00, null, 30);INSERT INTO EMP values (7782, \'CLARK\', \'MANAGER\', 7839, \'1981-06-09\', 2450.00, null, 10);INSERT INTO EMP values (7788, \'SCOTT\', \'ANALYST\', 7566, \'1987-04-19\', 3000.00, null, 20);INSERT INTO EMP values (7839, \'KING\', \'PRESIDENT\', null, \'1981-11-17\', 5000.00, null, 10);INSERT INTO EMP values (7844, \'TURNER\', \'SALESMAN\', 7698, \'1981-09-08\', 1500.00, 0.00, 30);INSERT INTO EMP values (7876, \'ADAMS\', \'CLERK\', 7788, \'1987-05-23\', 1100.00, null, 20);INSERT INTO EMP values (7900, \'JAMES\', \'CLERK\', 7698, \'1981-12-03\', 950.00, null, 30);INSERT INTO EMP values (7902, \'FORD\', \'ANALYST\', 7566, \'1981-12-03\', 3000.00, null, 20);INSERT INTO EMP values (7934, \'MILLER\', \'CLERK\', 7782, \'1982-01-23\', 1300.00, null, 10);-- 插入工资等级数据INSERT INTO SALGRADE (GRADE, LOSAL, HISAL) values (1, 700, 1200);INSERT INTO SALGRADE (GRADE, LOSAL, HISAL) values (2, 1201, 1400);INSERT INTO SALGRADE (GRADE, LOSAL, HISAL) values (3, 1401, 2000);INSERT INTO SALGRADE (GRADE, LOSAL, HISAL) values (4, 2001, 3000);INSERT INTO SALGRADE (GRADE, LOSAL, HISAL) values (5, 3001, 9999);-- 验证数据SELECT \'部门表数据:\' AS info;SELECT * FROM dept;SELECT \'员工表数据:\' AS info;SELECT * FROM emp;SELECT \'工资等级表数据:\' AS info;SELECT * FROM salgrade;

结语

通过这40道SQL基础练习题,我们系统地学习了SQL的核心语法和常用函数。掌握这些基础知识对于数据库操作和数据分析非常重要。建议在实际项目中多加练习,熟练掌握这些SQL技巧。

练习建议

  1. 循序渐进:从简单的SELECT语句开始,逐步学习复杂的查询
  2. 理解原理:不仅要会写SQL,更要理解每个函数和语法的作用
  3. 多练习:在实际项目中多加练习,熟能生巧
  4. 查阅文档:遇到不熟悉的函数时,及时查阅MySQL官方文档
  5. 性能优化:在掌握基础语法后,学习SQL性能优化技巧