MySql查询语句小汇总二(DQL语句)

多表查询:

       分类:合并结果集,连接查询,子查询

 

一:合并结果集

如果两张表的列类型和列数相同,可以进行合并,

关键字:union(去除重复行);union all(不去除重复行)

     

例:
select * from cd union all select * from ad;

      

 

 

 

 

 

 

 

 

二:连接查询

       分类:内连接,外链接(左外连接,右外连接,全外链接(MySql不支持)),自然连接

 

1,内连接

       1.1,直接查询两张表会得到笛卡尔积表

             

             

1.2,方言写法:查询表stu 和表teacher,得到每个学生的姓名,对应的课程,课程老师等信息;

      

Select s.name , s.age, t.name, t.class from stu s, teacher t where s.classID=t.id;

             

             

       1.3,标准的写法:

      

Select s.name , s.age, t.name inner t.class from stu s inner join teacher t on s.classID=t.id;

             

             

 

 

 

 

 

 

 

 

 

 

 

 

2,外连接:

2.1,左外连接:(左外即左表为主表,左表记录无论是否满足条件都会查询出来,而右表只有满足条件才能出来,左表不满足条件的记录,右表部分都为NULL)

             

Select * from stu s left outer join teacher t on s.classID=t.id;

             

             

2.2,右外连接:右表就无论满足条件都会查询出来,而左表只有满足条件才能查询出来,右表不满足条件的记录,其左表部分都为NULL

             

 Select * from stu s right outer join teacher t on s.classID=t.id;

             

             

2.3,全连接:在其他数据库中使用full outer join实现全连接,但是MySql不支持,我们可以使用union来完成全连接。在左外查询语句和右外查询语句之间加上union,得到左外连接和右外连接的结果集,可以间接实现全连接。

             

             

             

 

 

 

 

 

 

 

三:子查询

       子查询即查询中包含查询

 

1,出现的位置:

       1.1,where后作为条件存在

       例:查询stu表中年龄最大的人的详细信息

      

Select * from stu where age = (select max(age) from stu);

      

      

       1.2,from后作为表存在(多行多列)

       例:查询上课程1的学生的姓名,性别,年龄信息:

      

Select s.name,s.sex,s.age from (select * from stu where classID=1) s;

      

      

 

2,条件:    

2.1,单行单列:是指子查询返回的是单一值的标量,如一个数字或一个字符串,也是子查询中最简单的返回形式。 可以使用 = > < >= <= <> 这些操作符对子查询的标量结果进行比较,通常子查询的位置在比较式的右侧 (Mysql中“<>”表示不等号的意思,有的地方写成!=或#)

              例:查询stu表中年龄大于平均年龄的人的信息

            

  Select * from stu where age>(select avg(age) from stu);

             

             

2.2,多行单列:指子查询返回的结果集是 N 行一列,该结果通常来自对表的某个字段查询返回。 
    可以使用 = > < >= <= <> 这些操作符对子查询的标量结果进行比较,通常子查询的位置在比较式的右侧 
    可以使用 IN、ANY、SOME 和 ALL 操作符,不能直接使用 = > < >= <= <> 这些比较标量结果的操作符。 

              例子:查询年龄大于,课程标号为1的人的,所有人的详细信息

             

 Select * from stu age> all (select age from stu where classID=1);

             

             

2.3,单行多列:指子查询返回的结果集是一行 N 列,该子查询的结果通常是对表的某行数据进行查询而返回的结果集。 

              例子:查询stu表中,跟“张三”选修同一课程且年龄相同的人的信息

            

  Select * from stu where (classID,age) in (select classID,age from stu where where name=‘张三’ ) ;

             

             

       2.4,多行多列:指子查询返回的结果集是 N 行 N 列的一个表数据。 

例句:

SELECT * FROM article WHERE (title,content,uid) IN (SELECT title,content,uid FROM blog);

             

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

四:子查询中关键字举例

 

1,any关键字:any关键词的意思是“对于子查询返回的列中的任何一个数值,如果比较结果为TRUE,就返回TRUE”。

       例:如果“10>any(10,21,11,3,21,11)”,由于10>3,所以该判断会返回true。

 

2,in关键字:使用in进行子查询,这个我们在日常写sql的时候是经常遇到的。in的意思就是指定的一个值是否在这个集合中,如何在就返回TRUE;否则就返回FALSE了。

       例子:查询stu表中男性,且选过课的人的信息

select * from stu where sex='男' and exists
(select *
from teacher
where stu.classID=teacher.id);

   

   

3,all关键字:all必须与比较操作符一起使用。all的意思是“对于子查询返回的列中的所有值,如果比较结果为TRUE,则返回TRUE”

例:如果“10 >all(2, 4, 5, 1)”,由于10大于集合中的所有值,所以这条判断就返回TRUE;而如果为“10 >all(20, 3, 2, 1, 4)”,这样的话,由于10小于20,所以该判断就会返回FALSE

 

 

4,独立子查询:独立字查询是不依靠外部查询的结果就能单独运行的查询语句;什么叫依赖外部查询,我们看下面的例子

       例子:查询stu表中,男性,且选过课的人的信息       方式1:

select * from stu
where sex=’男’ and classID in
(select id from teacher);

              方式2:

select * from stu
where sex=’男’ and exits
(select * from teacher
where stu.classID=teacher.id);

      

      

对于sql语句1,我们将子查询单独复制出来,也是可以单独执行的,就是子查询与外部查询没有任何关系。

对于sql语句2,我们将子查询单独复制出来,就无法单独执行了,由于sql语句2的子查询依赖外部查询的某些字段,这就导致子查询就依赖外部查询,就产生了相关性。

 

5,exists谓词:EXISTS是一个非常牛叉的谓词,它允许数据库高效地检查指定查询是否产生某些行。根据子查询是否返回行,该谓词返回TRUE或FALSE。与其 它谓词和逻辑表达式不同的是,无论输入子查询是否返回行,EXISTS都不会返回UNKNOWN,对于EXISTS来说,UNKNOWN就是FALSE。 还是上面的语句,获得城市为hangzhou,并且存在订单的用户。

 

 

 

四:子查询的优化问题

很多查询中需要使用子查询。使用子查询可以一次性的完成很多逻辑上需要多个步骤才能完成的SQL操作,同时也可以避免事务或者表锁死。子查询可以使查询语 句很灵活,但子查询的执行效率不高。

  子查询时,MySQL需要为内层查询语句的查询结果建立一个临时表。然后外层查询语句再临时表中查询记录。查询完毕 后,MySQL需要撤销这些临时表。因此,子查询的速度会受到一定的影响。如果查询的数据量比较大,这种影响就会随之增大。

  在MySQL中可以使用连接查 询来替代子查询。连接查询不需要建立临时表,其速度比子查询要快

 

 

不能优化的子查询: 
  1、mysql不支持子查询合并和聚合函数子查询优化,mariadb对聚合函数子查询进行物化优化; 
  2、mysql不支持from子句子查询优化,mariadb对from子句子查询进行子查询上拉优化; 
  3、mysql和mariadb对子查询展开提供有限的支持,如对主键的操作才能进行上拉子查询优化; 
  4、mysql不支持exists子查询优化,mariadb对exists关联子查询进行半连接优化,对exists非关联子查询没有进一步进行优化; 
  5、mysql和mariadb不支持not exists子查询优化; 
  6、mysql和mariadb对in子查询,对满足半连接语义的查询进行半连接优化,再基于代价评估进行优化,两者对半连接的代价评估选择方式有差异; 
  7、mysql不支持not in子查询优化,mariadb对非关联not in子查询使用物化优化,对关联not in子查询不做优化; 
  8、mysql和mariadb对>all非关联子查询使用max函数,<all非关联子查询使用min函数,对=all和非关联子查询使用exists优化; 
  9、对>some和>any非关联子查询使用min函数,对<some和<any非关联子查询使用max函数,=any 和=some子查询使用半连接进行优化,对>some和>any关联子查询以及<some和<any关联子查询只有exists 优化。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是王小贱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值