首页 > 数据库 >mysql-多表查询

mysql-多表查询

时间:2023-08-07 15:56:10浏览次数:50  
标签:多表 name suppliers mysql 查询 fruits id select

小知识:

1.为表取别名

  因为是对两张表进行查询了,那么每次写表名的话就有点麻烦,所以用一个简单的别名来代表表名

  格式:表名 as 别名

2.为字段取别名

  给字段名取别名的原因是为了有些字段名显示得更加清楚,比如:

  select f_price as '价格' from fruits;

 3.sql语句执行的顺序问题

 sql执行顺序:(1) from  (2) on  (3) join  (4) where  (5) group by  (6) avg, sum...  (7) having  (8) select  (9) distinct  (10) order by

也就是说,我们每次执行的sql语句都是从from开始的。

基于两张表

  搭建查询环境:前面已经有了一张表了,现在再增加一张suppliers(供应商)表和前面那个fruits表创建练习,也就是说让fruits表中的s_id字段指向suppliers表的主键值,创建一个外键约束关系。

create table if not exists suppliers(

s_id int primary key not null comment '主键,供应商编号',

s_name varchar(50) not null comment '供应商名称',

s_city varchar(50) null comment '服务城市',

s_zip varchar(10) null comment '服务电话',

s_call varchar(20) not null comment '供应商电话') comment '供应商表';

  其实这里并没有达到真正的外键约束关系,只是模拟,让fruits表中的s_id中的值能匹配到suppliers表中的主键值,通过手动添加这种数据,来达到这种关系,反正是死数据,也不再添加别的数据,就不用建立外键约束关系了,这里要搞清楚。

insert into suppliers(s_id, s_name, s_city, s_zip, s_call) values

(101, 'Supplies A', '天津', '400000', '18075'),

(102, 'Supplies B', '重庆', '400000', '44333'),

(103, 'Supplies C', '上海','400000', '90046'),

(104, 'Supplies D', '中山','400000', '11111'),

(105, 'Supplies E', '太原', '400000', '22222'),

(106, 'Supplies F', '北京', '400000', '45678'),

(107, 'Supplies G', '郑州', '400000', '33332');

 

 1.普通双表连接查询

  问题:查询水果的供应商编号、供应商名字、水果名称、水果价格

  分析:看下要求,就知道要查询两张表,如果需要查询两张表,那么两张表的关系必定是外键关系,或者类似于外键关系(类似于也就是说两张表并没有真正加外键约束,但是其特点和外键是一样的,就像上面我们手动创建的两张表一样,虽然没有设置外键关联关系,但是其特性跟外键关系是一样的)。

select s.s_id, s.s_name, f.f_name, f.f_price  from fruits as f, suplliers as s where f.s_id = s.s_id;

 解释:这里使用了表别名,并且这里是连接两张表的关系是在于fruits中的s_id等于suppliers中的s_id,也说是fruits表中记录了供应商的编号,通过该编号就能在suppliers表中找到对应的供应商的详细信息,就这样,两张表就联系起来了。

注意:第一个执行的是from,所以上面为表取别名,在语句的任何地方都可以使用。

2.内连接查询

知道了上面两张表基本的连接查询后,内连接查询就很简单了,因为内连接跟上面的作用是一样的,唯一的区别就是语法的不一样

  语法:表名 inner join 表名 on 连接条件;

问题:查询水果的供应商编号、供应商名字、水果名称、水果价格

select s.s_id, s.s_name, f.f_name, f.f_price from fruits as f inner join suppliers as s on f.s_id = s.s_id;

 还需要知道一个特殊一点的东西,那就是自连接查询,什么是自连接查询?就是涉及到的两张表都是同一张表。

  问题:查询供应商f_id = 'a1' 的水果供应商提供的其他水果种类

select f2.f_id, f2.f_name from fruits as f1 inner join fruits as f2 on f1.s_id = f2.s_id and f1.f_id = 'a1';

 解释:把fruits表分开看成是两张完全一样的表,在f1表中找到f_id = 'a1' 的s_id,然后到f2这张表中去查找和该s_id相等的记录,也就查询出来了问题所需要的结果。还有另一种方法,不用内连接查询也可以做到,下面会讲解,这里先给出答案,到时可以回过头来看看这个问题。

select f_id, f_name from fruits where s_id = (select s_id from fruits where f_id = 'a1');

 效果和内连接查询是一样的,其实原理都是一样的,还是借助了两张表,只是这个更容易让人理解,可以通过这个来去理解上面那个自连接查询。

3.外连接查询

  内连接是将符合查询条件(符合连接条件)的行返回,也就是相关联的行就返回。

  外连接除了返回相关联的行之外,将没有关联的行也会显示出来。

  为什么需要将不没关联的行也显示出来呢?这就要根据不同的业务需求了,就比如,order和customers,顾客可以有订单也可以没订单,现在需要知道所有顾客的下单情况,而我们不能够只查询出有订单的用户,而把没订单的用户丢在一边不显示,这个就跟我们的业务需求不相符了,有人说,既然知道了有订单的顾客,通过单表查询出来不包含这些有订单顾客,不就能达到我们的要求吗,这样是可以,但是很麻烦,如何能够将其一起显示并且不那么麻烦呢?为了解决这个问题,就有了外连接查询这个东西了。

3.1 左外连接查询

 语法:表名 left join 表名 on 条件;

返回包括左表中的所有记录和右表中连接字段相等的记录,通俗点讲,就是除了显示相关联的行,还会将左表中的所有记录行度显示出来。用例子来展示一下所说效果把。

  由于上面我们所用到的fruits和suppliers中的记录都是设计好的,并没有哪个供应商没有提供水果,现在为了体现左外连接的效果,在suppliers中增加两条记录,fruits中并没有对应这两条记录得水果信息

insert into suppliers values

(108, 'Supplies T', '江西', '33333', '11111'),

(109, 'Supplier Y', '江西', '22222', '44444'); 

 select s.s_id, s.s_name, f.f_id, f.f_name from suppliers as s left join fruits as f on s.s_id = f.s_id;

  解释:suppliers表是在left join的左边,所以将其中所有记录度显示出来了,有关联项的,也有没有关联项的。这就是左外连接的意思,将左边的表所有记录都显示出来(前提是按照我们所需要的字段,也就是select 后面所选择的字段)。如果将suppliers表放left join的右边,那么就不会在显示108和109这两条记录了。来看看

select s.s_id, s.s_name, f.f_id, f.f_name from fruits as f left join suppliers as s on s.s_id = f.s_id;

 3.2 右外连接查询

语法:表名 right join 表名 on 条件;  返回包括右表中的所有记录和右表中连接字段相等的记录,其实跟左外连接差不多,就是将右边的表内容给全部显示出来。

select s.s_id, s.s_name, f.f_id, f.f_name from friuts as f right join suppliers as s on s.s_id = f.s_id;

  这条语句执行出来的效果跟上面左外连接一样,就是调换了一下位置,其实效果还是一样的。

 

 注意:left join 和right join 这只是一种写法,其中还有另一种写法 left outer join 和 right outer join

   一般写这种复杂查询的时候,写sql语句的顺序应该是先从from写起。

4. 复合条件连接查询

在连接查询(内连接、外连接)过程中,通过添加过滤条件,限制查询结果,使查询结果更加准确,通俗点讲,说是将连接查询时的条件更加细化。

问题一:在fruits和suppliers表中使用inner join语法查询suppliers表中s_id为107的供应商的供货信息?

select s.s_id, s.s_name, f.f_id, f.f_name from suppliers as s inner join fruits as f on s.s_id = f.s_id and s.s_id = 107;

 问题二:在fruits表和suppliers表之间,使用inner join语法进行内连接查询,并对查询结果进行排序

select s.s_id, s.s_name, f.f_id, f.f_name from suppliers as s inner join fruits as f on s.s_id = f.s_id order by s.s_id;  //对f.s_id进行升序排序,默认的是asc,所以不用写

 

 

 对s.s_id进行排序其实也就是对f.s_id进行排序,效果是一样的,因为条件就是s.s_id=f.s_id。

子查询

  子查询,将查询一张表得到的结果来充当另一个查询的条件,这样嵌套的查询就称为子查询

1. 带any、some关键字的子查询          

 

搭建环境

create table if not exists tb11 (num1 int not null);

create table if not exists tb12 (num2 int not null);

insert into tb11 values (1), (5), (13), (27);

insert into tb12 values (6), (14), (11), (20);

any关键字接在一个比较操作符的后面,表示若与子查询返回的任何值比较为true,则返回true,通俗点讲,只要满足任意一个条件,就返回true。

select num1 from tb11 where num1 > any (select num2 from tb12);

 这里就是将tb12表中查询的结果放在前一个查询语句中充当条件参数,只要num1大于其结果中的任意一个数据,那么就算匹配。

some关键字和any关键字的用法一样,作用也相同。

2. 带all关键字的子查询

使用all时表示需要同时满足所有条件

select num1 from tb11 where num1> all (select num2 from tb12);

 num1需要大于所有查询到的结果才算匹配。

3. 带exists关键字的子查询

exists关键字后面的参数是任意一个子查询,如果子查询有返回记录行,则为true,外层查询语句将会进行查询,如果子查询没有返回任何记录行,则为false,外层查询语句将不会进行查询。

select * from tb11 where exists (select * from tb12 where num2 = 3);  //查询tb12中有没有num2=3的记录,有的话则会将tb11的所有记录查询出来,没有的话,不做查询。

 4. 带in关键字的子查询

这个in关键字的作用跟单表查询的in是一样的,不过这里in中的参数放的是一个子查询语句。

select s_id, f_id, f_name from fruits where s_id in (select s_id from suppliers whwre s_id = 107);

 5. 带比较运算符的子查询

  除了使用关键字all, any, some等之外,还可以使用普通的比较运算符来进行比较。比如我们上面讲解内连接查询的时候,就用过子查询语句,并且还是用的"="这个比较运算符,这里就不做多解释了,可以往上面看一下。

合并查询结果

  利用union关键字,可以将查询出的结果合并到一张结果集中,也就是通过union关键字将多条select语句连接起来,注意:合并结果集,只是增加了表中的记录,并不是将表中的字段增加,仅仅是将记录行合并到一起。其显示的字段应该是相同的,不然不能合并。

  union [all] 的使用

         union:不使用关键字all,执行的时候会删除重复的记录,所有返回的行度是唯一的,

         union all:不删除重复航也不对结果进行自动排序。

         语法:select 字段名,... from 表名 union [all] select 字段名,... from 表名

   问题:查询所有价格小于9的水果的信息,查询s_id等于101或103所有水果的信息,使用union连接查询结果

select s_id, f_name, f_price from fruits where f_price < 9 union all select s_id, f_name, f_price from fruits where s_id = 101 or s_id = 103;

  解释:显示的字段都是s_id,f_name,f_price,只是将两个的记录行合并到一张表中。仅仅增加的是记录行,而显示的字段还是那三个,没有增加。

 

 使用union,而不用union all的话,重复的记录将会被删除掉。

select s_id, f_name, f_price from fruits where f_price < 9 union select s_id, f_name, f_price from fruits where s_id = 101 or s_id = 103;

 

使用正则表达式查询

  这个非常简单,就是使用regexp关键字来指定正则表达式,画一张表格,就能将下面所有的度覆盖掉。

 1. 查询以特定字符或字符串开头的记录

select * from fruits where f_name regexp '^b';  //查询以b开头的记录

 就讲解这一个,下面这些的形式跟这个一模一样,唯一的差别就在正则表达式不一样,一般使用这种模糊查询,使用mysql中的'_'和'%'就已经足够了。

2. 查询以特定字符或字符串结尾的记录

3. 用符号"."来替代字符串中的任意一个字符

4. 使用"*"和"+"来匹配多个字符

 5. 匹配指定字符串

 6. 匹配指定字符中的任意一个

 7. 匹配指定字符以外的字符

 8. 使用{n,}或者{n,m}来指定字符串连续出现的次数

标签:多表,name,suppliers,mysql,查询,fruits,id,select
From: https://www.cnblogs.com/k0065/p/17610358.html

相关文章

  • MySQL问题记录Can't connect to MySQL server on 'localhost' (10061)解决方法
    登录MySQL提示Can'tconnecttoMySQLserveron'localhost'(10061)进入安装目录bin目录,执行mysqld--install,启动MySQL点击查看代码cdD:\soft\MySQL\MySQLServer5.7\binmysqld--installnetstartmysql提示启动失败最后执行mysqld--initialize--user=root--......
  • 10亿数据、查询<10s,论基于OLAP搭建广告系统的正确姿势
    更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群由于流量红利逐渐消退,越来越多的广告企业和从业者开始探索精细化营销的新路径,取代以往的全流量、粗放式的广告轰炸。精细化营销意味着要在数以亿计的人群中优选出那些最具潜力的目标受众,这无疑对......
  • mysql密码破解
    mysql破解密码1.设置mysql免密登陆#vim/etc/my.cnf.d/mysql-server.cnf#主配置文件[mysqld]下面添加以下内容[mysqld]skip-grant-tables#免密的登陆#重启mysql#systemctlrestartmysqld2.查看数据库中用户的密码,此时是加密状态mysql>selecthost,user,au......
  • 10亿数据、查询<10s,论基于OLAP搭建广告系统的正确姿势
    更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群 由于流量红利逐渐消退,越来越多的广告企业和从业者开始探索精细化营销的新路径,取代以往的全流量、粗放式的广告轰炸。精细化营销意味着要在数以亿计的人群中优选出那些最具潜力的目标受......
  • mp-分页查询的学习
    使用limit关键字进行分页步骤:创建配置类,创建一个拦截器,在尾部添加limit实现分页然后创建IPage对象,利用Page实现IPage<User>page=newPage<>(1,3); 自定义分页查询:自己在resources中创建自定义查询方法,进行如下配置随后在对应的接口中将User类改为IPage IPage<User>......
  • 快递查询:提前分析物流信息
    越来越多的人选择线上购物,使得快递行业日益繁忙,物流信息庞杂且分散,面对每天不断增加的快递单量,人工查询跟踪快递状态变得十分耗时且繁琐,为了解决当下的一系列问题,我们推出“快递批量查询高手”,是一款强大的工具,批量导入快递、筛选分析单号,一键查看物流信息等等。首先,第一步,我们要进......
  • MySQL事务与锁
    锁锁粒度数据库锁定机制简单来说,就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种规则。MySQL数据库由于其自身架构的特点,存在多种数据存储引擎,每种存储引擎的锁定机制都是为各自所面对的特定场景而优化设计,所以各存储引擎的锁定机制也有较大区别......
  • 批量查询物流信息,轻松筛选未签收标记物流信息
    快递已经成为我们生活里不可或缺的一部分,但有时会因为物流的信息差或未签收情况,从而导致丢失退回,当推出一款高效、速度、准确地掌握快递的信息,显得至关重要,现在我们推出一款工具,让您批量化查询快递单号,轻松筛选未签收的快递信息,方便快捷,让您准确随时掌握快递信息。第一步:进入快递查......
  • MySQL Execution Plan -- IN条件与ORDER BY组合优化
    测试环境MySQL版本:5.7.27-30-logPerconaServer(GPL),wsrep_31.39涉及表结构:CREATETABLE`scout_job`(`task_id`varchar(22)NOTNULLDEFAULT''COMMENT'任务id',`job_id`int(20)unsignedNOTNULLAUTO_INCREMENTCOMMENT'jobId',......
  • 1-linux下mysql8.0.33安装
    在互联网企业的日常工作/运维中,我们会经常用到mysql数据库,而linux下mysql的安装方式有三种:1.mysqlrpm安装2.mysql二进制安装3.mysql源码安装今天就为大家讲讲linux下mysql8.0.33版本rpm方式的安装。1.前提1.1.系统版本CentOS7.9.2009命令:cat/etc/redhat-release[root@cent79-2~]......