【MySQL】复合查询——基本单表查询、多表查询、自连接、子查询、使用from进行子查询、合并查询

news2024/11/18 23:26:00

文章目录

  • MySQL
  • 复合查询
    • 1. 基本单表查询
    • 2. 多表查询
    • 3. 自连接
    • 4. 子查询
      • 4.1 单行子查询
      • 4.2 多行子查询
      • 4.3 多列子查询
      • 4.4 使用from进行子查询
    • 5. 合并查询
      • 5.1 union
      • 5.2 union all

MySQL

在这里插入图片描述

  

复合查询

  数据库的复合查询是指在一个查询中结合使用多个查询条件或查询子句,以获取满足多个条件的记录。 这种查询方式在关系型数据库中非常常见,特别是在处理复杂的数据检索需求时。复合查询通常涉及一下操作:连接、子查询、聚合函数、分组、排序、筛选等。

1. 基本单表查询

  MySQL的基本单表查询都是对一张表进行查询。

简单示例:我们创建一张表用于员工信息的存储:

  其中包括员工的编号 id ,员工的姓名和工作,员工的薪资和入职日期,以及员工的部门编号和所对应的领导编号。其中编号 empno 作为我们的主键。

mysql> create table emp(
    -> empno int unsigned primary key,
    -> ename varchar(20),
    -> job varchar(20),
    -> salary int,
    -> hiredate date,
    -> deptno int,
    -> );

在这里插入图片描述

  忘了添加或者后续想要添加关于员工其他的列信息?我们可以使用 alter 进行对应表的修改以此来添加我们所需要的列信息。

mysql> alter table emp
    -> add column mgr int;

在这里插入图片描述

  

查看表的结构:

desc emp;

在这里插入图片描述
  

插入信息:

mysql> insert into emp values(1001,'张三','总经理',10000,'2000-1-1',10,NULL);
mysql> insert into emp values(1002,'张花','员工',5000,'2005-7-4',10,1001);
mysql> insert into emp values(1003,'李四','经理',8000,'2002-3-12',20,NULL);
mysql> insert into emp values(1004,'李华','销售',8000,'2006-3-12',10,1001);
mysql> insert into emp values(1005,'王五','销售',7800,'2007-11-28',20,1002);
mysql> insert into emp values(1006,'赵六','销售',6700,'2008-5-18',10,1001);
mysql> insert into emp values(1007,'小美','员工',5000,'2010-2-08',20,1003);
mysql> insert into emp values(1008,'小帅','经理',9000,'2002-3-12',30,NULL);
mysql> insert into emp values(1009,'小蓝','员工',7600,'2007-5-22',30,NULL);

在这里插入图片描述

  

查看表的所有信息:

mysql> select *from emp;

在这里插入图片描述
  

查询工资高于6000且工作为 ‘员工’ 的雇员:

select * from emp where (salary>=6000 and job='员工');

在这里插入图片描述
  

按照部门号升序而雇员的工资降序排序:

select * from emp order by deptno ,salary desc;

在这里插入图片描述
  

显示工资最高的员工的名字、岗位和工资:

select ename,job,salary from emp where salary =(select max(salary) from emp);

在这里插入图片描述
  

使用年薪进行降序排序:

select ename ,salary*12 as '年薪' from emp order by 年薪 desc;

在这里插入图片描述
  

显示工资高于平均工资的员工信息:

select ename, salary from emp  where salary>(select avg(salary) from emp);

在这里插入图片描述
  

显示每个部门的平均工资和最高工资:

select deptno, format(avg(salary), 2)as '平均工资' , max(salary)
from emp group by deptno;

在这里插入图片描述
  

显示每种岗位的雇员总数,平均工资:

select job,count(*)as'人员数量',
format(avg(salary),2)as'平均工资' 
from emp 
group by job; 

在这里插入图片描述

  

2. 多表查询

  实际开发中往往数据来自不同的表,所以需要多表查询。

为了实现多表查询,我们再创建一个员工部门表用于保存用户的部门名称和地点:

mysql> create table dept( 
    -> deptno int,
    -> dname varchar(20),
    -> loc varchar(20)
    -> );

在这里插入图片描述
  

插入对应的员工部门编号和信息:

mysql> insert into dept values(10,'产品部','上海');
mysql> insert into dept values(20,'宣传部','北京');
mysql> insert into dept values(30,'技术部','深圳');

mysql> select * from dept;

在这里插入图片描述
  

显示各个员工的姓名,工资,工资和部门信息:

  通常在多表查询的时候,我们会使用笛卡尔积将两张表格进行连接,然后使用where语句筛选出有效的信息。

在这里插入图片描述
  

显示各个员工的姓名,工资,工资和部门信息:

select ename,salary,emp.deptno,dname,loc 
from emp,dept 
where emp.deptno=dept.deptno;

在这里插入图片描述

  

显示部门号为10的部门名,员工名和工资:

select ename,salary,emp.deptno  
from emp,dept 
where emp.deptno=dept.deptno  
and dept.det.deptno=10;

在这里插入图片描述

  

3. 自连接

  自连接是指在同一张表连接查询。

显示员工张花的领导的编号和姓名:

方法一 使用的子查询:

  我们先使用 select 语句查找到张花领导的 empno ,然后我们使用 select+where 查询后的结果作为条件,再次进行 select+where 查询输出领导的编号和姓名。

select empno,ename 
from emp 
where emp.empno=(select mgr from emp where ename='张花');

在这里插入图片描述
  

方法二 使用多表查询(自查询):

  这里使用到表的别名,from emp leader, emp worker,给自己的表起别名,将同一张表去两个名字(这样我们就会有两张表了,这两张表的内容完全一致,只是名字不同),同时因为要先做笛卡尔积,所以别名可以先识别。

select leader.empno,leader.ename 
from emp leader, emp worker  // 这里对表取别名,为leader worker
where leader.empno=worker.mgr 
and worker.ename='张花';

在这里插入图片描述

  

4. 子查询

  子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询。这允许我们在一个查询中使用另一个查询的结果。子查询可以出现在 SELECT、FROM 或 WHERE 子句中,甚至在其他子查询中。子查询为 SQL 查询提供了极大的灵活性和复杂性,使你能够执行各种复杂的数据检索和计算任务。

4.1 单行子查询

  返回一行记录的子查询。

同上,显示员工张花的领导的编号和姓名:

  我们先使用 select 语句查找到张花领导的 empno ,然后我们使用 select+where 查询后的结果作为条件,再次进行 select+where 查询输出领导的编号和姓名。

select empno,ename 
from emp 
where emp.empno=(select mgr from emp where ename='张花');

在这里插入图片描述
  

4.2 多行子查询

  返回多行记录的子查询。

查询和10号部门的工作岗位相同的雇员的名字,岗位,工资,部门号:

select ename,job,salary,deptno 
from emp 
where job 
in (select job fromemp where deptno=10) ;

在这里插入图片描述

  

显示工资比部门30的所有员工的工资高的员工的姓名、工资和部门号:

select ename,salary,deptno 
from emp 
where salary > all(select salary from emp wheredeptno=30);

在这里插入图片描述

  

显示工资比部门30的任意员工的工资高的员工的姓名、工资和部门号(包含自己部门
的员工):

select ename,salary,deptno 
from emp 
where salary >any(select salary from emp wheredeptno=30);

在这里插入图片描述

  

4.3 多列子查询

  单行子查询是指子查询只返回单列,单行数据;多行子查询是指返回单列多行数据,都是针对单列而言的,而多列子查询则是指查询返回多个列数据的子查询语句。

查询和张花的岗位相同的所有雇员,且不含SMITH本人:

select ename 
from emp
where(job)=(select job from emp where ename='张花 ') 
and ename <> '张花';

在这里插入图片描述

  

4.4 使用from进行子查询

  子查询语句出现在from子句中。这里要用到数据查询的技巧,把一个子查询当做一个临时表使用。

显示每个高于自己部门平均工资的员工的姓名、部门、工资、平均工资:

select ename,deptno,salary,format(asal,2) 
from emp,
(select avg(salary) asal,deptno dt from emp group by deptno ) tmp
where emp.salary>tmp.asal and emp.deptno=tmp.dt;

  子查询:

(select avg(sal) asal, deptno dt from EMP group by deptno) tmp

  我们从EMP表中为每个deptno计算平均薪水(命名为asal)并将部门编号(命名为dt)一起选择出来。然后,这个子查询的结果集被命名为tmp。

  主查询:

select ename, deptno, sal, format(asal,2) from EMP, tmp

  主查询从EMP表和tmp子查询结果中选择ename(员工名字)、deptno(部门编号)、sal(薪水)以及格式化后的平均薪水asal。这里,format(asal,2)会将asal格式化为两位小数的形式。

  连接条件:

where EMP.sal > tmp.asal and EMP.deptno=tmp.dt

  这部分是连接条件,它指定了如何将EMP表与tmp子查询结果连接起来。具体来说,它要求:

  EMP.sal(员工的薪水)必须大于tmp.asal(部门的平均薪水)。

  EMP.deptno(员工的部门编号)必须等于tmp.dt(子查询中的部门编号)

  
在这里插入图片描述

  

查找每个部门工资最高的人的姓名、工资、部门、最高工资:

select emp.ename,emp.salary ms 
from emp, 
(select max(salary) ms,deptno from emp group by deptno) tmp 
where emp.deptno=tmp.deptno and emp.salary=tmp.ms;

  子查询:

(select max(salary) ms, deptno from emp group by deptno) tmp

  我们从emp表中为每个deptno(部门编号)选择最高的薪水(命名为ms)。子查询的结果集被命名为tmp。

  主查询:

select emp.ename, emp.salary ms   
from emp, tmp

  主查询从emp表和tmp子查询结果中选择emp表中的ename(员工名字)和salary(薪水)。这里,emp.salary被重命名为ms,以与子查询中的ms列名保持一致。

  连接条件:

where emp.deptno=tmp.deptno and emp.salary=tmp.ms

  这部分是连接条件,它指定了如何将emp表与tmp子查询结果连接起来。具体来说,它要求:

  emp.deptno(员工的部门编号)必须等于tmp.deptno(子查询中的部门编号)。

  emp.salary(员工的薪水)必须等于tmp.ms(子查询中的该部门的最高薪水)。

  
在这里插入图片描述

  

显示每个部门的信息(部门名,编号,地址)和人员数量:

方法1 使用多表:

select dept.dname,dept.deptno,dept.loc,count(*) '部门人数' 
from emp, dept 
where emp.deptno=dept.deptno 
group by dept.deptno,dept.dname,dept.loc;

  选择的列:

select dept.dname, dept.deptno, dept.loc, count(*) '部门人数'

  这部分选择了dept表中的dname(部门名称)、deptno(部门编号)和loc(部门位置)三列,同时还使用count( * )函数计算每个部门的员工数量,并将这个数量命名为’部门人数’。

  数据来源:

from emp, dept

  这里,查询从emp表和dept表中选择数据。由于使用了逗号分隔两个表,这是一个隐式连接(也称为笛卡尔积),这意味着它会返回emp表和dept表所有可能的行组合。

  连接条件:

where emp.deptno=dept.deptno

  这个条件确保了我们只连接那些emp表中的deptno与dept表中的deptno相匹配的记录。

  分组:

group by dept.deptno, dept.dname, dept.loc

  由于使用了count(*)聚合函数,我们需要通过GROUP BY子句来指定如何对结果进行分组。这里,我们按照dept表的deptno、dname和loc列进行分组,确保每个唯一的部门组合都会得到一个计数。

  
在这里插入图片描述

  

方法2 使用子查询:

select dept.deptno,dname,mycnt,loc 
from dept,(select count(*) mycnt,deptno from emp group by deptno) tmp
where dept.deptno=tmp.deptno;

  子查询:

(select count(*) mycnt, deptno from emp group by deptno) tmp

  我们从emp表中为每个deptno(部门编号)计算员工数量(命名为mycnt)。子查询的结果集被命名为tmp。

  主查询:

select dept.deptno, dname, mycnt, loc  
from dept, tmp

  主查询从dept表和tmp子查询结果中选择dept表的deptno(部门编号)、dname(部门名称)、mycnt(员工数量)以及loc(部门位置)。

  连接条件:

where dept.deptno=tmp.deptno

  这部分是连接条件,它指定了如何将dept表与tmp子查询结果连接起来。具体来说,它要求dept表中的deptno必须等于tmp子查询结果中的deptno。

  
在这里插入图片描述

  

5. 合并查询

  在实际应用中,为了合并多个select的执行结果,可以使用集合操作符 union,union all。合并查询通常指的是将两个或多个查询的结果组合在一起。在SQL中,你可以使用UNION或UNION ALL运算符来合并两个或多个SELECT语句的结果集。

5.1 union

  union:该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中的重复行。

显示工资大于6000或职位是销售的雇员(去重):

select ename,salary,job 
from emp 
where salary>6000 
union 
select ename,salary,jobob 
from emp 
where job='销售';

在这里插入图片描述

  

5.2 union all

  union all:该操作符用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行。

显示工资大于6000或职位是销售的雇员(不去重):

select ename,salary,job 
from emp 
where salary>6000 
union all  
select ename,salary,jobob 
from emp 
where job='销售';

在这里插入图片描述

            

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1541406.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

常见技术难点及方案

1. 分布式锁 1.1 难点 1.1.1 锁延期 同一时间内不允许多个客户端同时获得锁&#xff1b; 1.1.2 防止死锁 需要确保在任何故障场景下&#xff0c;都不会出现死锁&#xff1b; 1.2.3 可重入 特殊的锁机制&#xff0c;它允许同一个线程多次获取同一个锁而不会被阻塞。 1.2…

五、分布式锁-redission

源码仓库地址&#xff1a;gitgitee.com:chuangchuang-liu/hm-dingping.git 1、redission介绍 目前基于redis的setnx特性实现的自定义分布式锁仍存在的问题&#xff1a; 问题描述重入问题同一个线程无法多次获取统一把锁。当方法A成功获取锁后&#xff0c;调用方法B&#xff0…

【C++】如何用一个哈希表同时封装出unordered_set与unordered_map

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》《算法》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 1.哈希桶源码 2.哈希…

19.删除链表的倒数第N个结点 92.反转链表II

给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5]示例 2&#xff1a; 输入&#xff1a;head [1], n 1 输出&#xff1a;[]示例 3&#xff1a; …

模拟-算法

文章目录 替换所有的问号提莫攻击Z字形变换外观数列数青蛙 替换所有的问号 算法思路&#xff1a; 从前往后遍历整个字符串&#xff0c;找到问号之后&#xff0c;就遍历 a ~ z 去尝试替换即可。 class Solution {public String modifyString(String s) {char[] ss s.toCharA…

删除字符串--给你一个字符串S,要求你将字符串中出现的所有“gzu“子串删除,输出删除之后的S。

输入描述: 输入一行字符串S&#xff0c;长度不超过100。 输出描述: 输出进行删除操作之后的S。 #include <stdio.h> #include <stdlib.h> #include <string.h>//结合了串的模式匹配算法思路int main(){char s[100];char a[3]{g,z,u};gets(s);int nstrlen…

数据库语言一些基本操作

1&#xff0c;消除取值重复的行。 例如&#xff1a;查成绩不及格的学号&#xff1a;SELECT DISTINCT sno FROM SC WHERE grade<60. 这里使用DISTINCT表示取消取值重复的行。 2&#xff0c;比较。 例如&#xff1a;查计算机系全体学生的姓名&#xff1a;SELECT Sname FROM…

C++一维数组练习oj(3)

为什么C的一维数组练习要出要做那么多的题目&#xff1f;因为我们是竞赛学生&#xff01;想要将每个知识点灵活运用的话就必须刷大量的题目来锻炼思维。 我使用的是jsswoj.com这个刷题网站&#xff0c;当然要钱... C一维数组练习oj(2)-CSDN博客这是上一次的题目讲解 这道题有…

java每日一题——买啤酒(递归经典问题)

前言&#xff1a; 非常喜欢的一道题&#xff0c;经典中的经典。打好基础&#xff0c;daydayup!!!啤酒问题&#xff1a;一瓶啤酒2元&#xff0c;4个盖子可以换一瓶&#xff0c;2个空瓶可以换一瓶&#xff0c;请问10元可以喝几瓶 题目如下&#xff1a; 啤酒问题&#xff1a;一瓶…

[Halcon学习笔记]在Qt上实现Halcon窗口的字体设置颜色设置等功能

1、 Halcon字体大小设置在Qt上的实现 在之前介绍过Halcon窗口显示文字字体的尺寸和样式&#xff0c;具体详细介绍可回看 &#xff08;一&#xff09;Halcon窗口界面上显示文字的字体尺寸、样式修改 当时介绍的设定方法 //Win下QString Font_win "-Arial-10-*-1-*-*-1-&q…

传输层——UDP协议

端口号(Port) 端口号标识了一个主机上进行通信的不同的应用程序&#xff0c;准确来说&#xff0c;端口号标识了主机上唯一的一个进程。 在TCP/IP协议中, 用 "源IP", "源端口号", "目的IP", "目的端口号", "协议号" 这样一个…

罗德与施瓦茨联合广和通全面验证RedCap模组FG132系列先进性能

近日&#xff0c;罗德与施瓦茨联合广和通完成Redcap(Reduce Capability)功能和性能验证。本次测试使用R&SCMX500 OBT(One Box Tester)无线通信测试仪&#xff0c;主要验证广和通RedCap模组FG132系列射频性能以及IP层吞吐量&#xff0c;包括RedCap上下行吞吐量和射频指标如矢…

Java 自定义线程池实现

自定义线程池 简介任务图示阻塞队列 BlockingQueue<T>ReentrantLock代码 线程池 ThreadPool工作线程类 Worker 拒绝策略接口代码测试类 TestThreadPool为什么需要j i&#xff1f;&#xff08;lambad表达式相关&#xff09; 测试结果拒绝策略&#xff1a;让调用者自己执行…

c++常考基础知识(2)

二.c关键字 关键字汇总 c中共有63个关键字&#xff0c;其中包括int&#xff0c;char&#xff0c;double等类型关键字&#xff0c;if&#xff0c;else&#xff0c;while&#xff0c;do&#xff0c;等语法关键字&#xff0c;还有sizeof等函数关键字。 三.数据结构 1.数组&#x…

Navicat 干货 | 探索 PostgreSQL 的外部数据包装器和统计函数

PostgreSQL 因其稳定性和可扩展性而广受青睐&#xff0c;为开发人员和数据管理员提供了许多有用的函数。在这些函数中&#xff0c;file_fdw_handler、file_fdw_validator、pg_stat_statements、pg_stat_statements_info 以及 pg_stat_statements_reset 是其中的重要函数&#x…

浩哥带你做项目,纯免费教学

浩哥带你做项目 一、YiYi-Web项目开发1. 简介2. 技术栈2.1 后端开发环境2.2 前端开发环境 3.项目截图 二、计算机游戏程序设计&#xff08;基础篇&#xff09;三、RuoYi-Cloud项目学习1.功能介绍2.项目截图 四、鸿蒙应用开发五、软考六、Linux基础知识学习 最近浩哥社区群涌进大…

【Python从入门到进阶】51、电影天堂网站多页面下载实战

接上篇《50、当当网Scrapy项目实战&#xff08;三&#xff09;》 上一篇我们讲解了使用Scrapy框架在当当网抓取多页书籍数据的效果&#xff0c;本篇我们来抓取电影天堂网站的数据&#xff0c;同样采用Scrapy框架多页面下载的模式来实现。 一、抓取需求 打开电影天堂网站&…

VMware Workstation Pro 17虚拟机超级详细搭建(含redis,nacos,docker, rabbitmq,sentinel,elasticsearch....)(一)

今天从零搭建一下虚拟机的环境&#xff0c;把nacos&#xff0c;redis等微服务组件还有数据库搭建到里面&#xff0c;首先看到的是我们最开始下载VMware Workstation Pro 17 之后的样子&#xff0c;总共一起应该有三部分因为篇幅太长了 下载地址 : VMware - Delivering a Digit…

echarts睡眠分期

效果 echarts核心配置 option {tooltip: {trigger: axis // 触发方式为axis&#xff0c;表示数据项图形触发&#xff0c;此时坐标轴上的刻度也会显示提示信息。},xAxis: {show: false,type: category,data: [2024-02-02 12:00:01,2024-02-02 12:00:02,2024-02-02 12:00:03,20…

stm32启动文件里面的__main和主函数main()

一、__main和main()之间的关系 先来对stm32启动过程简单学习 启动文件里面的Reset_Handler&#xff1a; 调用过程&#xff1a; stm32在启动后先进入重启中断函数Reset_Handler&#xff0c;其中会先后调用SystemInit和__main函数&#xff0c; __main函数属于c库函数&…