select/in/join/exists/union
首页->学习资料->微服务治理->sql教程 关键词: 发布时间:2014-12-22 04:04:48 浏览次数:1529

select 语句

group by 子句,分组查询

对查询结果(已经通过where子句过滤之后的数据,也就是先select再group by),按照某个字段,进行分组!

 

group by 字段!

在分组的结果中,只会显示组内的头一条记录! 如果需要排序,最好先排序后分组

分组的作用,不在查询每个组内的具体数据。而其作用主要是在分组统计上:

例:select * from student where age>20 group by classid;

 

合计函数

此时需要使用统计函数(合计函数)加以配合!

合计函数例如:count() 可以统计结果中的记录数,但是一旦使用了分组查询,则只会统计组内的数据!

例:统计每个班有多少个人;

select count(*) as ct from student group by classid;

 

count(),统计记录数。典型的使用是 count(*),但是除了*之外,是可以使用字段名的!

其中,只要记录存在,则count(*)就会统计到数据,而如果相应的字段为null,则count(字段)不会统计上数据:


sum(字段表达式),统计和,对某个字段求和!

avg(),平均值

max(字段表达式),最大值

min(字段表达式),最小值

group_concat(字段表达式),组内连接字符串


分组排序

默认的分组后会按照分组字段对结果进行排序。可以group by子句指定排序的方式(升序ASC和降序DESC)

 

多字段分组

使用逗号分隔开多个分组字段即可!统计时,会按照多个字段的组合分组生成结果!

例如:统计每个班级内的男生和女生的数量!

select count(*),classid,sex from student group by classid,sex;

 

如果是多字段分组,需要查看每个分组的的详细情况:

可以使用关键字with rollup关键字来回滚统计:

 

having子句,条件子句

功能上与where类似,都是条件子句!

主要的区别,在于执行时机:

执行时机:

where,是开始时,从数据源中检索数据的条件。

而 having,是在筛选,分组之后,在得到的结果中,再次进行筛选的语法!(所以他们的顺序类似于这样where->group by ->having)

因此 having的结果一定是 where 已经过滤之后的结果!

having的作用在于,对结果进行二次处理!



为啥要有 having:where没有办法与合计函数一起使用!原因在于执行顺序问题!

典型的应该使用别的形式为 having完成条件表达式:

 

order by 排序子句

对结果进行排序的语句!

 

order by 字段名 [asc|desc], [字段名[asc|desc],]

可见可按照多个字段进行排序


原则是,先按照第一个字段进行排序,如果字段值相同,则采用第二个,以此类推!


 

limit 子句

限制结果记录数的子句!

从所有的结果中,选择部分结果的子句!

select * from tablename limit start,size;

上面的是记录的位置:

可以从某个位置开始,取得多少条!

limit start, size;

start:起始位置

size,取得的记录数

注意,第二个参数size是长度,而不是终止位置!


select * from tablename limit size;

还有一个简写,省略start起始位置,表示从第一条记录开始:


 

 

select的子句的总结

select子句的全部子句

书写顺序

字段表达式,from子句,where子句,group by子句,having子句,order by子句,limit子句。

书写顺序,与执行顺序!几乎是一样的!

执行顺序

from

where

group by

字段表达式,合计函数表达式

having

order by

limit

 

书写顺序不能错,但是子句几乎都可以省略!省略表示不发生操作!

 

 

子查询,sub-query

出现在其他语句内部的查询语句,称之为子查询

 

 

子查询的分类

分类的依据!

两种分类依据:

1, 依据子查询出现的位置!

where型子查询,出现在where子句内!

from 型子查询,出现在from子句内!

 

2, 依据子查询的返回数据的格式!

标量子查询,返回值是一个数据,称之为标量子查询!

列子查询,返回一个列,

行子查询,返回一个行,

表子查询,返回的是一个二维表


 

 

from型

例子:找出每个班里面,身高最高的学生信息

select * from (select * from student order by height desc) as tmp group by classid;

但是这样查有一个问题,如果同班里面有几个相同身高且均为最高的学生时,只能查出一个;因为group by 默认只显示第一个;可以用in条件,后面会说到


留意:from 需要一个数据还是一个表,需要将子查询返回的数据,导出成表即可!

为子查询起个别名即可!

 

列子查询

返回值应该是一列!

由于返回的是一列,是一类数据,看成是一个集合!


例子:找出每个班里面,身高最高的学生信息;那么用子查询解决不了的用in就可以解决了

select * from student where height in(select max(height) as height from student group by classid);

 

典型的列子查询使用 in, not in作为子查询的条件!

 

列子查询,还可以使用

= some

!= all

或者其他的运算符配合 some() 和 all()语法完成!

some(), 表示集合中的一部分!

all(),集中的全部

测试:

=some()相当于in么?

!=some()相当于什么?不相当于not in!

哪个相当于not in ,与集合内的任何一个值都不相等!

!=all() 是not in!

any就是some,一个功能!

 

行子查询

场景:找到最高并且最有钱!

使用行子查询可以,一次性查出来一个行(多个行)使用行进行匹配:

上面使用了 (),构建了一行!与子查询的行作比较!

例子:找出最高也最有钱的学生

select * from student where (height,money)=(select max(height),max(money) from student);

 

 

(not) exists型子查询

判断依据不是根据子查询所返回的数据!只是根据子查询是否存在返回数据来看;

如果子查询存在返回数据,则exists返回真。反之,返回假!

出现在where条件内:

例子:班级已经不存在的学生! (假设班级id最大为3);

select * from student where exists(select * from class where id>3);

结果为空;


 

 

连接查询,join

连接,多个表记录之间的连接!

 

场景:

需要得到一个学生列表,要求是,展示:

学生,性别,班级名字

 

此时需要不单从学生表获取数据,还需要从班级表获得数据!

 

语法:

from 表名1  join  表名2     on 连接条件



过程是,先执行 from子句,需要连接join。

 

 

两个特殊的地方:

join ,连接

on ,连接条件

 

join 连接语法

除了默认的连接之外,有其他形式的连接方式

 

内连接

外连接,左外连接,右外连接,[全外连接,也是外连接,但是不是mysql所支持的]

交叉连接

自然连接

 

 

内连接,inner join

记录与真实的记录连接,称之为内连接!(两条真实存在的记录的连接)

mysql默认的连接就是 inner join


 

内连接,可以连接省略条件!

on可以省略:相当于连接条件永远成立!

返回值是一个笛卡尔积!


外连接,left join,right join

分成:左外连接left join,右外连接right join!

 

连接的记录,可能是一方不存在的!(两条记录中,可能某条不存在)

 

总结:内连接,外连接差别不大,只是外连接会将没有连接成功的记录,也出现最终的连接的结果内,而内连接,连接的结果只有连接成功的(两条记录都存在的)

 

 

注意好左外与右外的区别:

区别在于,那个表的记录(指的是连接失败的记录),会最终出现在连接结果内?

 

什么是左表和右表?

join关键字前面的(左边的)左表,join关键字后边的(右边的)右表!

 

左外:如果出现左表记录连接不上右表记录的,左表记录会出现正在最终的连接结果内!而右表记录相应设置成NULL。

右外:如果出现右表记录连接不上左表记录的,右表记录会出现正在最终的连接结果内!而左表记录相应设置成NULL。


因此,可以交换表的位置,达到使用left与right join 混用的的目的!

 

 

 

交叉连接,cross join

 

结果与内连接一致!

 

有时,在获得笛卡尔积时,显式的使用交叉连接!

 

交叉连接相当于是没有条件的内连接!

 

 

自然连接,natural join

 

mysql,自动判断连接条件,帮助我们完成连接!

典型的条件就是,表中的同名字段!


 

而自然连接也分内连接与外连接!

自然内连接:natural join

自然左外:natural left join

自然右外:natual right join


 

 

总结:

最终的效果只有:内,左外,右外!

交叉,特殊的内!

自然,相当于自动判断连接条件,完成内,左外,右外!

 

连接条件,on,using

on,后面使用一个连接条件表达式!

using(连接字段),要求使用同名字段进行连接!


 

using 的特别地方:

会对字段列表做一次整理!将连接字段作为一次显示!


 

 


union查询,联合查询

将多个查询的结果,并列到一个结果集合内!

 

此时,获得所有男生,按照身高升序排序。

获得所有的女生,按照身高降序排序。

此时:


 

此时,将两个结果联合起来:

注意,在union是,如果子句中出现了 order by,则需要子句出现在小括号内!

此时,子句的order by 也会在union的时候,会忽视掉!需要子句配合limit一起使用order by

 

union 的连接的两个子句,不要求实同表,只要求,列的数量相同!

union会在联合时:主动去掉相同的记录:此时,可以使用 all关键字加以修正:

 

select语句的选项

distinct,取消相同的记录

默认是 all,可以不写,表示所有的记录都出现!

赞:(0)
踩:(0)
相关文章
find_in_set在集合中查找
sql查询自定义排序field函数
sql显示表结构及索引
sql修改表
添加、删除索引
sql分组
sql子查询
sql多表更新
sql建表同时插入数据
sql多表删除
热门文章
win7中将文件拷贝到虚拟机linux下
phpexcel设置行高及列宽,背景颜色,
rabbitmq无法启动
intellij idea不显示git push按钮
php7中使用mongodb的aggregate进行
centos7.4 64位下swoole安装及配置
laravel页面静态化的方法
navicate连接mycat报1184错误
单点登录sso原理及php实现方式及de
devops-jenkins容器为pending状态
好评文章
phpexcel设置行高及列宽,背景颜色,
php7中使用mongodb的aggregate进行
intellij idea打开文件所在文件夹
windows下使用MongoDB Compass Com
win7中将文件拷贝到虚拟机linux下
laravel 中悲观锁 & 乐观锁的使用
单点登录sso原理及php实现方式及de
navicate连接mycat报1184错误
rabbitmq无法启动
laravel整合dingo/api方法步骤:jwt
标签
rabbitmq mysql备份 elasticsearch golang swoole
我的项目
【github】www.github.com/hurong241
【码云】gitee.com/hu_rong/projects
【docker hub】hub.docker.com/repositories/hurong241
【packagist】packagist.org/users/hurong241/packages
站点信息
建站时间:2011年
文章数:607篇
浏览数:946734
粤ICP备18028092号-1  微信:hurong241