复合查询与子查询:深入解析 scott 样例数据库中的多表查询

时间:2024-10-27 10:03:43

复合查询与子查询:深入解析 scott 样例数据库中的多表查询

在当前数字化管理的商业环境中,运用数据库进行精确的信息检索显得尤为重要。然而,其中的子查询操作宛如一道复杂的谜题,不少数据库用户在此过程中可能会遇到难题。以下,我们选取数据库中的scott样例数据库(即一个简易的公司管理系统)作为研究对象,对复合查询和子查询的相关操作进行深入探讨。

mysql> select ename, sal, grade from EMP, SALGRADE where EMP.sal between losal and hisal;
+--------+---------+-------+
| ename  | sal     | grade |
+--------+---------+-------+
| SMITH  |  800.00 |     1 |
| ALLEN  | 1600.00 |     3 |
| WARD   | 1250.00 |     2 |
| JONES  | 2975.00 |     4 |
| MARTIN | 1250.00 |     2 |
| BLAKE  | 2850.00 |     4 |
| CLARK  | 2450.00 |     4 |
| SCOTT  | 3000.00 |     4 |
| KING   | 5000.00 |     5 |
| TURNER | 1500.00 |     3 |
| ADAMS  | 1100.00 |     1 |
| JAMES  |  950.00 |     1 |
| FORD   | 3000.00 |     4 |
| MILLER | 1300.00 |     2 |
+--------+---------+-------+
14 rows in set (0.02 sec)

Scott样例数据库概况

Scott样例数据库模拟了公司管理系统的基本功能。其中,它包含了三个核心的表格:EMP职员表、DEPT部门表以及工资表。这些表格记录了公司的基础信息,是进行查询操作的基础。就像在现实公司中,员工基本信息表、部门架构表和薪资表构成了公司运营的框架一样。在这样的结构中,精确地获取所需数据,成为了数据分析和管理决策的关键。在现实企业里,无论是哪个部门或业务,若要依靠数据来辅助决策,都离不开这种数据库结构的支撑。

mysql> select * from EMP WHERE deptno = (select deptno from EMP where ename='smith');
+--------+-------+---------+------+---------------------+---------+------+--------+
| empno  | ename | job     | mgr  | hiredate            | sal     | comm | deptno |
+--------+-------+---------+------+---------------------+---------+------+--------+
| 007369 | SMITH | CLERK   | 7902 | 1980-12-17 00:00:00 |  800.00 | NULL |     20 |
| 007566 | JONES | MANAGER | 7839 | 1981-04-02 00:00:00 | 2975.00 | NULL |     20 |
| 007788 | SCOTT | ANALYST | 7566 | 1987-04-19 00:00:00 | 3000.00 | NULL |     20 |
| 007876 | ADAMS | CLERK   | 7788 | 1987-05-23 00:00:00 | 1100.00 | NULL |     20 |
| 007902 | FORD  | ANALYST | 7566 | 1981-12-03 00:00:00 | 3000.00 | NULL |     20 |
+--------+-------+---------+------+---------------------+---------+------+--------+
5 rows in set (0.01 sec)

单行子查询

单行子查询在查询特定信息方面具有其独特优势,就好比解决一个针对性强的问题。比如,当我们需要查看与SMITH同部门的员工时,就可以运用单行子查询。通过参考数据库中的记录,根据关联字段,在EMP表中精确筛选出同部门的员工。在实际应用中,只要掌握了这一技巧,当需要查找与特定员工具有相同个别条件的记录时,就能快速锁定目标数据。以大型公司为例,若想了解与某位明星员工同部门的人员信息,单行子查询便能发挥其作用。


mysql> select ename,job,sal,empno from emp where job in 
(select distinct job from emp where deptno=10) and deptno<>10;
+-------+---------+---------+--------+
| ename | job     | sal     | empno  |
+-------+---------+---------+--------+
| JONES | MANAGER | 2975.00 | 007566 |
| BLAKE | MANAGER | 2850.00 | 007698 |
| SMITH | CLERK   |  800.00 | 007369 |
| ADAMS | CLERK   | 1100.00 | 007876 |
| JAMES | CLERK   |  950.00 | 007900 |
+-------+---------+---------+--------+
5 rows in set (0.01 sec)

多行子查询,这是一个功能相当强大的工具。在需要获取多行记录时,我们便不得不借助它。

首先关注in关键字,通过它我们可以查询与10号部门工作相同的雇员信息,包括姓名、岗位、工资和部门号,但排除了10号部门自身。这一用法凸显了in关键字在多行子查询中的特殊作用,它能有效地筛选出满足多个条件的数据。接着看all关键字,比如要找出工资高于部门30所有员工的员工姓名、工资和部门号,使用all关键字可以确保结果的准确性。而any关键字则允许我们查询工资高于部门30中任意员工的员工姓名、工资和部门号,满足了特定查询需求。在处理复杂的员工薪资和岗位结构时,运用多行子查询结合这些关键字,可以轻松解决一系列复杂的数据筛选难题。

mysql> select ename, sal, deptno from EMP where sal > all(select sal from EMP where deptno=30);
+-------+---------+--------+
| ename | sal     | deptno |
+-------+---------+--------+
| JONES | 2975.00 |     20 |
| SCOTT | 3000.00 |     20 |
| KING  | 5000.00 |     10 |
| FORD  | 3000.00 |     20 |
+-------+---------+--------+
4 rows in set (0.01 sec)

From子句中的子查询

mysql> select ename, sal, deptno from EMP where sal > any(select sal from EMP where deptno=30);
+--------+---------+--------+
| ename  | sal     | deptno |
+--------+---------+--------+
| ALLEN  | 1600.00 |     30 |
| WARD   | 1250.00 |     30 |
| JONES  | 2975.00 |     20 |
| MARTIN | 1250.00 |     30 |
| BLAKE  | 2850.00 |     30 |
| CLARK  | 2450.00 |     10 |
| SCOTT  | 3000.00 |     20 |
| KING   | 5000.00 |     10 |
| TURNER | 1500.00 |     30 |
| ADAMS  | 1100.00 |     20 |
| FORD   | 3000.00 |     20 |
| MILLER | 1300.00 |     10 |
+--------+---------+--------+
12 rows in set (0.01 sec)

子查询若置于from子句中,情形颇为有趣。它此时如同一个临时的表格。在处理复杂数据源或需临时生成数据样本进行查询的实际应用中,from子句中的子查询便能大显身手。以跨部门、业务逻辑复杂的场景为例,单纯使用原始表查询,效率可能不高。然而,若将子查询视作临时表,与from子句结合,便能快速高效地操作。此方法可有效地整合与分析数据,使数据库的数据运用更为灵活。

Union操作符

mysql> select ename, deptno, sal, format(asal,2) from EMP,  
(select avg(sal) asal, deptno dt from EMP group by deptno) tmp where
 EMP.sal > tmp.asal and EMP.deptno=tmp.dt;
+-------+--------+---------+----------------+
| ename | deptno | sal     | format(asal,2) |
+-------+--------+---------+----------------+
| KING  |     10 | 5000.00 | 2,916.67       |
| JONES |     20 | 2975.00 | 2,175.00       |
| SCOTT |     20 | 3000.00 | 2,175.00       |
| FORD  |     20 | 3000.00 | 2,175.00       |
| ALLEN |     30 | 1600.00 | 1,566.67       |
| BLAKE |     30 | 2850.00 | 1,566.67       |
+-------+--------+---------+----------------+
6 rows in set (0.09 sec)

Union操作符确实是个十分实用的工具。用它,结果集会自动清除重复的行。想象一下,面对一个数据庞大、重复信息繁多的文件,谁不想有个工具能自动清理掉重复的内容?比如,当我们需要找出工资超过2500元或职位名称特定的人时,Union操作符就能确保结果既精确又整齐,避免重复带来的困扰。在企业进行多条件人员分组统计时,这一功能非常有用,它能保证数据的条理清晰和统计结果的精确无误。

UnionAll和Union这两个操作符虽有许多共通之处,却也各有不同。UnionAll的作用是合并两个结果集,形成它们的并集,且在合并过程中不会删除任何重复的行。这就像我们在收集各种数据时,希望保留所有信息,保持数据的原始状态。例如,当我们需要找出工资超过25000或职位名称特定的员工时,UnionAll就不会对可能重复的数据进行删除,从而更好地保留了数据的完整性。这种操作在整合部分业务的原生数据时尤其有用。

mysql> select EMP.ename, EMP.sal, EMP.deptno, ms from EMP,
 (select max(sal) ms, deptno from EMP group by deptno) tmp  where
  EMP.deptno=tmp.deptno and EMP.sal=tmp.ms;
+-------+---------+--------+---------+
| ename | sal     | deptno | ms      |
+-------+---------+--------+---------+
| BLAKE | 2850.00 |     30 | 2850.00 |
| SCOTT | 3000.00 |     20 | 3000.00 |
| KING  | 5000.00 |     10 | 5000.00 |
| FORD  | 3000.00 |     20 | 3000.00 |
+-------+---------+--------+---------+
4 rows in set (0.01 sec)

在使用数据库进行查询时,你是否遇到过难以克服的数据筛选和整合难题?期待你的点赞,同时欢迎你将这篇文章转发。若能在评论区分享你的数据库查询经验,那就更完美了。

mysql> select DEPT.dname, DEPT.deptno, DEPT.loc,count(*) '部门人数' from EMP,
 DEPT where EMP.deptno=DEPT.deptno group by DEPT.deptno,DEPT.dname,DEPT.loc;
+------------+--------+----------+--------------+
| dname      | deptno | loc      | 部门人数     |
+------------+--------+----------+--------------+
| ACCOUNTING |     10 | NEW YORK |            3 |
| RESEARCH   |     20 | DALLAS   |            5 |
| SALES      |     30 | CHICAGO  |            6 |
+------------+--------+----------+--------------+
3 rows in set (0.02 sec)