暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

SQL语言基础知识(练习和答案)

oracleace 2023-07-03
573

关于号主,姚远:

  • Oracle ACE(Oracle和MySQL数据库方向)。

  • Oracle MAA 大师。

  • 华为云MVP。

  • 《MySQL 8.0运维与优化》的作者。

  • 拥有 Oracle 10g和12c OCM等20+数据库认证。

  • 曾任IBM公司数据库部门经理。

  • 20+年DBA经验,服务2万+客户。


01

练习


同学们使用我提供的样本数据进行练习会得到和我这里给出的一样的结果。

  • 使用between查询工资在一万和一万五千之间的员工。

参考答案如下:

    select ename,sal from emp where sal between 10000 and 15000;
    • 因为当地生活成本上涨,公司决定给在CHICAGO工作的员工增加10%的工资

    参考答案

      update emp set sal=sal*1.1 where deptno
      (select deptno from dept where loc='CHICAGO');
      • 找出姓名最后一个字面是n或者第二字面是i的员工。

        select * from emp where ename like '%n' or '_i%';


        • 按照部门升序和入职日期降序员工名。

        参考答案如下:

          select ename,deptno,hiredate from emp order by deptno asc,hiredate asc;




          • 查询2010年之前入职的姓名、工资和增加10%后的工资(updated salary)和入职时间。

          参考答案如下:

            postgres=# select ename,sal,sal*1.1 "Updated Salary",hiredate from emp where hiredate<'2010-01-01';
            ename | sal | Updated Salary | hiredate
            ------------+----------+----------------+------------
            Grace | 12000.00 | 13200.000 | 2000-12-02
            Ben | 8000.00 | 8800.000 | 2004-09-11
            (2 rows)


            • 因为公司经营困难,解雇2010年前入职的老员工(公司裁员都是先裁老员工,因为老员工工资高)

              delete from emp where hiredate<'2010-01-01';
              • 解雇所有在NEW YORK工作的员工,把他们从员工表中删除。

              参考答案

                delete from emp where deptno=(select deptno from dept where loc='NEW YORK');
                • 列出所有佣金不为空的员工的姓名、工资、佣金和工资和佣金的总和。

                参考答案:

                  select ename,sal,comm,sal+comm total_salary from emp where comm is not null;
                  • 找出不在部门1和部门3的员工的姓名。

                  参考答案如下:

                    select ename,deptno from emp where deptno not in (1,3);


                    • 查询部门名和部门的工资总和,提示:需要用到emp表、deptno表和相关子查询。

                      select dname,(select sum(sal) from emp where deptno=d.deptno) dept_sum_sal  from dept d;
                      • 查询所有员工的姓名和入职时间,根据入职时间将员工进行分类成资深程度

                      早于2001之前入职员工列为创始人

                      在2001年和2019年之间的列为老员工

                      在2020年之后的列为新员工

                        select ename,hiredate,'Founder' as "Hire Date" from emp where hiredate <'2001-01-01'
                        union
                        select ename,hiredate,'Senior Employees' as "Hire Date" from emp where hiredate between '2001-01-01' and '2019-12-31'
                        union
                        select ename,hiredate,'Junior Employees' as "Hire Date" from emp where hiredate >'2019-12-31';


                        NOT IN表示不在集合中。

                        我们先向部门表中插入新一条记录

                          insert into dept(deptno,dname) values(5,'Operation');

                          查询部门表中一个员工也没有的部门

                            mysql> select deptno,dname from dept where deptno not in (select deptno from emp);
                            +--------+-----------+
                            | deptno | dname |
                            +--------+-----------+
                            | 5 | Operation |
                            +--------+-----------+
                            1 row in set (0.00 sec)


                            思考题

                            如果这个时候有个员工的部门号为空,比如这个员工是总裁,他不属于任何部门。

                              insert into emp(empno,ename,deptno,sal) values(10,'Frank',NULL,12000.00);

                              再次执行前面的SQL,得到的结果集为空,也就是说这个SQL有bug。

                                mysql> select deptno,dname from dept where deptno not in (select deptno from emp);
                                Empty set (0.00 sec)

                                使用两种方法对这个SQL进行改写,解决这个问题

                                  mysql> select deptno,dname from dept where deptno not in (select deptno from emp where deptno is not null);
                                  +--------+-----------+
                                  | deptno | dname |
                                  +--------+-----------+
                                  | 5 | Operation |
                                  +--------+-----------+
                                  1 row in set (0.00 sec)


                                  mysql> select deptno,dname from dept d where not exists (select 1 from emp e where d.deptno=e.deptno);
                                  +--------+-----------+
                                  | deptno | dname |
                                  +--------+-----------+
                                  | 5 | Operation |
                                  +--------+-----------+
                                  1 row in set (0.00 sec)






                                  欢迎加我的微信,拉你进数据库微信群👇

                                  推荐文章👇

                                  试看《MySQL 8.0运维与优化》(清华大学出版社)

                                  Oracle和MySQL课程录像

                                  托业890分的Oracle ACE为您翻译国际大佬的雄文(合集)


                                  文章转载自oracleace,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                  评论