MySQL数据库基础(五)——SQL查询

MySQL数据库基础(五)——SQL查询

1、单表查询

一、查询全部字段

在SELECT语句中使用星号“”通配符查询全部字段
在SELECT语句中指定全部字段
select
from TStudent;java

二、查询指定字段

查询多个字段
select Sname,sex,email from TStudent;正则表达式

三、查询指定记录

在SELECT 语句中经过WHERE子句,对数据进行过滤,语法格式为:
SELECT 字段名1,字段名2,…,字段名n FROM 表名WHERE 查询条件
select Sname,sex,email,Class from TStudent where class='java';数据库

四、带IN关键字的查询

查询知足指定范围内的条件的记录,使用IN操做符,将全部检索条件用括号括起来,检索条件用逗号分隔开,只要知足条件范围内的一个值即为匹配项。
查新姓 王 刘 石的学生
select * from TStudent where left(sname,1) in ('王','刘','石');express

五、带BETWEEN AND的范围查询

查询某个范围内的值,该操做符须要两个参数,即范围的开始值和结束值,若是字段值知足指定的范围查询条件,则这些记录被返回。
如下查询条件,查询学号100到150的学生,包括100和150
select from TStudent where convert(studentid,signed) between 100 and 150
等价于
select
from TStudent where convert(studentid,signed)>=100
and convert(studentid,signed)<=150
自动转换类型
select * from TStudent where studentid between 100 and 150ide

六、带LIKE的字符匹配查询

百分号通配符‘%’,匹配任意长度的字符,甚至包括零字符
下划线通配符‘_’,一次只能匹配任意一个字符
查找姓名中间字为“志”字的学生
select from TStudent where sname like '' ;
查找姓名中有“志”字的学生
select
from TStudent where sname like '%志%';函数

七、查询空值

在SELECT语句中使用IS NULL子句,能够查询某字段内容为空记录。
查找邮箱是空值的记录
select * from s where email is null;性能

八、带AND的多条件查询

使用AND链接两个甚至多个查询条件,多个条件表达式之间用AND分开。
select * from TStudent where sex='男' and Class='net' and studentid&gt;20 and studentid&lt;50;code

九、带OR的多条件查询

OR操做符,表示只须要知足其中一个条件的记录便可返回。OR也能够链接两个甚至多个查询条件,多个条件表达式之间用AND分开。
select * from TStudent where sname like '%志%' or class='net';regexp

十、查询结果不重复

在SELECT语句中可使用DISTINCE关键字指示MySQL消除重复的记录值。
SELECT DISTINCT 字段名 FROM 表名;
查询一共有几个班
select distinct class from TStudent;blog

十一、用LIMIT限制查询结果的数量

LIMIT关键字能够返回指定位置的记录。
LIMIT [位置偏移量,] 行数
返回前10个学生
select from TStudent limit 10;
返回第11-20个学生,偏移量是10,就意味着从第11个开始取10条记录。
select
from TStudent limit 10,10;

十二、合并查询结果

利用UNION关键字,能够给出多条SELECT语句,并将它们的结果组合成单个结果集。合并时,两个表对应的列数和数据类型必须相同。各个SELECT语句之间使用UNION或UNION ALL关键字分隔。
要求第一个SQL语句返回的列和第二条返回的列数相同,
select studentid,sname from TStudent where studentid<=10
union
select studentid, sname from TStudent where sname like '王%';

1三、为表和字段取别名

为字段取别名
MySQL能够指定列别名,替换字段或表达式。
列名 [AS] 列别名
select studentid as 学号,sname as 姓名,sex as 性别 from TStudent
select studentid 学号,sname 姓名,sex 性别 from TStudent
为表取别名
为了方便操做或者须要屡次使用相同的表时,能够为表指定别名,用别名替表明原来的名称。
表名 [AS] 表别名
select a.studentid 学号,a.sname 姓名,a.sex 性别 from TStudent as a;
select a.studentid 学号,a.sname 姓名,a.sex 性别 from TStudent a;

2、多表链接查询

一、内链接查询

内链接(INNER JOIN)使用比较运算符根据每一个表共有的列的值匹配两个表中的行,并列出表中与链接条件相匹配的数据行,组合成新的记录。在内链接查询中,只有知足条件的记录才能出如今结果关系中。
语句3:隐式的内链接,没有INNER JOIN,造成的中间表为两个表的笛卡尔积。
select a.StudentID, a.Sname, b.mark from TStudent a, TScore b where a.StudentID=b.StudentID;
语句4:显示的内链接,通常称为内链接,有INNER JOIN,造成的中间表为两个表通过ON条件过滤后的笛卡尔积。
select a.StudentID, a.Sname, b.mark from TStudent a inner joinTScore b on a.StudentID=b.StudentID;
select a.StudentID,a.Sname,c.subJectName,b.mark from TStudent a join TScore b on a.StudentID=b.StudentID join TSubject c on b.subJectID=c.subJectID;
MySQL数据库基础(五)——SQL查询
若是某列只在一张表中,就能够不用指明是哪一个表中的列。
select a.StudentID,a.Sname,subJectName,mark from TStudent a join TScore b on a.StudentID=b.StudentID join TSubject c on b.subJectID=c.subJectID;
MySQL数据库基础(五)——SQL查询

二、外链接查询

外链接分为左链接、右链接、全链接。
外链接返回到查询结果集合中的不只包含符合链接条件的行,并且还包括左表(左外链接或左链接)、右表(右外链接或右链接)或两个边接表(全外链接)中的全部数据行。
外连不但返回符合链接和查询条件的数据行,还返回不符合条件的一些行。外链接分三类:左外链接(LEFT OUTER JOIN)、右外链接(RIGHT OUTER JOIN)和全外链接(FULL OUTER JOIN)。
三者的共同点是都返回符合链接条件和查询条件(即:内链接)的数据行。不一样点以下:
左外链接还返回左表中不符合链接条件单符合查询条件的数据行。
右外链接还返回右表中不符合链接条件单符合查询条件的数据行。
全外链接还返回左表中不符合链接条件单符合查询条件的数据行,而且还返回右表中不符合链接条件单符合查询条件的数据行。全外链接实际是上左外链接和右外链接的数学合集(去掉重复),即“全外=左外 UNION 右外”。
左链接
包含左边表的所有行(无论右边的表中是否存在与它们匹配的行),以及右边表中所有匹配的行。
左链接的结果集包括 LEFT OUTER子句中指定的左表的全部行,而不只仅是链接列所匹配的行。若是左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的全部选择列表列均为空值。 
select a.StudentID, a.Sname, b.mark from TStudent a left join TScore b on a.StudentID=b.StudentID;
MySQL数据库基础(五)——SQL查询
右链接:
右链接包含右边表的所有行(无论左边的表中是否存在与它们匹配的行),以及左边表中所有匹配的行。
右链接是左链接的反向链接。将返回右表的全部行。若是右表的某行在左表中没有匹配行,则将为左表返回空值。    
select a.StudentID, a.Sname, b.mark from TScore b right join TStudent a on a.StudentID=b.StudentID;
MySQL数据库基础(五)——SQL查询
全链接:
全链接返回左表和右表中的全部行。当某行在另外一个表中没有匹配行时,则另外一个表的选择列表列包含空值。若是表之间有匹配行,则整个结果集行包含基表的数据值。MySQL不支持全外链接。能够经过左外和右外求合集来获取全外链接的查询结果。
select a.StudentID, a.Sname, b.mark from TStudent a left join
TScore b on a.StudentID=b.StudentID
union
select b.StudentID, c.subJectName, b.mark from TScore b right join
TSubject c on b.subJectID=c.subJectID;
MySQL数据库基础(五)——SQL查询

三、交叉链接

交叉链接返回左表中的全部行,左表中的每一行与右表中的全部行组合。交叉链接有显式的和隐式的,不带ON子句,返回的是两表的乘积,也叫笛卡尔积。
FROM子句中的表或视图可经过内链接或全链接按任意顺序指定;可是,用左或右向外链接指定表或视图时,表或视图的顺序很重要。
隐式交叉链接,没有cross join
select a.StudentID, a.Sname, b.mark from TStudent a,TScore b where a.StudentID < 4;
显示交叉链接,有cross join
select a.StudentID, a.Sname, b.mark from TStudent a cross join TScore b where a.StudentID < 4;
MySQL数据库基础(五)——SQL查询

四、SQL查询的原理

第1、单表查询:根据WHERE条件过滤表中的记录,造成中间表;而后根据SELECT的选择列选择相应的列进行返回最终结果。
第2、两表链接查询:对两表求积(笛卡尔积)并用ON条件和链接链接类型进行过滤造成中间表;而后根据WHERE条件过滤中间表的记录,并根据SELECT指定的列返回查询结果。实例以下:
select a.StudentID, a.Sname, b.mark from TStudent a left join TScore b on a.StudentID=b.StudentID where a.StudentID < 10;
第3、多表链接查询:先对第一个和第二个表按照两表链接作查询,而后用查询结果和第三个表作链接查询,以此类推,直到全部的表都链接上为止,最终造成一个中间的结果表,而后根据WHERE条件过滤中间表的记录,并根据SELECT指定的列返回查询结果。

五、过滤条件

ON条件:过滤两个链接表笛卡尔积造成中间表的约束条件。
WHERE条件:在有ON条件的SELECT语句中是过滤中间表的约束条件。在没有ON的单表查询中,是限制物理表或者中间查询结果返回记录的约束。在两表或多表链接中是限制链接造成最终中间表的返回结果的约束。
将WHERE条件移入ON后面是不恰当的。推荐的作法是ON只进行链接操做,WHERE只过滤中间表的记录。

六、链接查询的适用场景

链接查询是SQL查询的核心,链接查询的链接类型选择依据实际需求。若是选择不当,非但不能提升查询效率,反而会带来一些逻辑错误或者性能低下。两表链接查询选择方式的依据:
A、查两表关联列相等的数据用内链接。
B、Col_L是Col_R的子集时用右链接。
C、Col_R是Col_L的子集时用左链接。
E、 Col_R和Col_L彼此有交集但彼此互不为子集时候用全链接。
F、求差操做的时候用联合查询。

3、对查询结果排序

MySQL中能够经过在SELECT使用ORDER BY子句对查询的结果进行排序。

一、单列排序

ASC表明结果会以由小往大的顺序列出,而 DESC 表明结果会以由大往小的顺序列出。默认升序ASC排序。
select from TStudent order by birthday asc;
select
from TStudent order by birthday desc;

二、多列排序

能够分别指定排序方向。
select a.StudentID,a.Sname,subJectName,mark from TStudent a join TScore b on a.StudentID=b.StudentID join TSubject c on b.subJectID=c.subJectID where c.subJectID='0001' order by mark desc,a.studentID desc;

4、分组查询

一、分组查询简介

分组查询是对数据按照某个或多个字段进行分组。
// 分组查询格式
SELECT column
FROM table
[WHERE condition]
[GROUP BY group_by_expression]
[HAVING group_condition] // 过滤条件为聚合函数,使用having
[ORDER BY column];
聚合函数只能出如今SELECT列表、HAVING子句和ORDER BY子句中,不能出如今WHERE子句中。若是要限制分组结果,只能使用HAVING子句。
使用group by关键字时,在select列表中能够指定的项目是有限制的,select语句中仅容许是被分组的列,或是为每一个分组返回一个值的表达式,例如用一个列名做为参数的聚合函数。
Where子句:从数据源去掉不符合搜索条件的数据;
GROUP BY子句:分组,使用统计函数(聚合函数)为每组计算统计值;
HAVING子句:在分好的组中去掉每组中不符合条件的数据行。

二、使用聚合函数查询

COUNT()函数
select class,COUNT(*) from TStudent group by class;
SUM()函数
查询每一个学生总分
select concat(a.StudentID,' ',a.sname) ss,SUM(b.mark) from TStudent a join TScore b on a.StudentID=b.StudentID group by ss;
AVG()函数
统计每一个班平均分
Select class,AVG(mark) from TStudent a join TScore b on a.StudentID=b.StudentID group by class;

三、多字段分组

统计每班每科平均分,须要按两列分组class和subJectName
select class,subJectName,AVG(mark) from TStudent a join TScore b on a.StudentID=b.StudentID join TSubject c on b.subJectID=c.subJectID group by class,subJectName;

四、使用HAVING过滤分组

查询平局分大于80的学生
select concat(a.StudentID,' ',a.sname) ss,avg(b.mark) m from TStudent a join TScore b on a.StudentID=b.StudentID group by ss having m>80;

五、GROUP BY和ORDER BY使用

查找平均分大于80分,按平均分排序。
select concat(a.StudentID,' ',a.sname) ss,avg(b.mark) m from TStudent a join TScore b on a.StudentID=b.StudentID group by ss having m>80 order by m;

六、在GROUP BY子句中使用WITH ROLLUP

使用GROUP BY的WITH ROLLUP子句能够检索出更多的分组聚合信息,不只仅能够检索出各组的聚合信息,还能检索出本组类的总体聚合信息。
select class,subJectName,AVG(mark) from TStudent a join TScore b on a.StudentID=b.StudentID join TSubject c on b.subJectID=c.subJectID group by class,subJectName with rollup;
可以统计每班每科的平均成绩,每班的平均成绩也能统计,所有班级的所有课程平均成绩也能统计。

5、子查询

一、带IN关键字的子查询

IN关键字进行子查询时,内层查询语句仅仅返回一个数据列,数据列里的值将提供给外层查询语句进行比较操做。
select * from TStudent where studentid in (select distinct studentid from TScore where mark>98);

二、带EXISTS关键字的子查询

EXISTS关键字后面的参数是一个任意的子查询,系统对子查询进行运算以判断子查询是否返回行,若是至少返回一行,那么EXISTS的结果为true,此时外层查询语句将进行查询;若是子查询没有返回任何行,那么EXISTS返回的结果是false,此时外层语句将不进行查询。
select from TStudent where studentid='01001' and exists (select from TScore where studentid='01001');

三、带ANY、SOME关键字的子查询

ANY和SOME关键字是同义词,表示知足其中任一条件,容许建立一个表达式对子查询的返回值列表进行比较,只要知足内层子查询中的任何一个比较条件,就返回一个结果做为外层查询的条件。
select from TStudent where studentid=any (select distinct studentid from TScore where mark>98)
等价于
select
from TStudent where studentid=some (select distinct studentid from TScore where mark>98);
等价于
select from TStudent where studentid in (select distinct studentid from TScore where mark>98);
子查询时还可使用其余的比较运算符,如<、<=、=、>=和!=等。
如下SQL语句子查询查出考试成绩大于98的学生的studentid,好比查出的结果有三个‘00010’,‘00021’,‘00061’,外查询将会查询比00010学号大的学生。
select
from TStudent where studentid>some (select distinct studentid from TScore where mark>98)
如下SQL语句子查询查出考试成绩大于98的学生的studentid,好比查出的结果有三个‘00010’,‘00021’,‘00061’,外查询将会查询比00061学号小的学生。
select * from TStudent where studentid&lt;some (select distinct studentid from TScore where mark&gt;98);

四、带ALL关键字的子查询

ALL关键字与ANY和SOME不一样,使用ALL时须要同时知足全部内层查询的条件。
如下SQL语句子查询查出考试成绩大于98的学生的studentid,好比查出的结果有三个‘00010’,‘00021’,‘00061’,外查询将会查询比00010学号小的学生。
select * from TStudent where studentid&lt;all (select distinct studentid from TScore where mark&gt;98)
如下SQL语句子查询查出考试成绩大于98的学生的studentid,好比查出的结果有三个‘00010’,‘00021’,‘00061’,外查询将会查询比00061学号大的学生。
select * from TStudent where studentid>all (select distinct studentid from TScore where mark>98);

6、使用正则表达式查询

正则表达式做用是匹配文本,将一个模式(正则表达式)与一个文本串进行比较。MySQL用WHERE子句对正则表达式提供了初步的支持,容许指定用正则表达式过滤SELECT检索出的数据。
在SQL查询语句中,查询条件REGEXP后所跟的东西做为正则表达式处理。

一、查询以特定字符或字符串开头的记录

字符‘^’匹配以特定字符或者字符串开头的文本。
select * from TStudent where sname regexp '^刘平';

二、查询以特定字符或字符串结尾的记录

字符‘$’匹配以特定字符或者字符串结尾的文本。
select * from TStudent where cardid regexp '36$';

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

字符‘.’匹配任意一个字符。
select * from TStudent where sname regexp '.康.';

四、使用"*"和"+"来匹配多个字符

星号‘’匹配前面的字符任意屡次,包括0次。
加号‘+’匹配前面的字符至少一次。
找出×××以19开始,以6结束的学生
select
from TStudent where cardid regexp '^19.6$'
找出×××号中有123的学生
select
from TStudent where cardid regexp '.123+.';

五、匹配指定字符串

正则表达式能够匹配指定字符串,只要匹配字符串在查询文本中便可,如要匹配多个字符串,多个字符串之间使用分隔符‘|’隔开。
select * from TStudent where sname regexp '武|尹|罗';

六、匹配指定字符中的任意一个

方括号“[]”指定一个字符集合,只匹配其中任何一个字符,即为所查找的文本。不支持汉字。
select from TStudent where email regexp '[w-z]';
select
from TStudent where cardid regexp '^[1-3,7]';

七、匹配指定字符之外的字符

“[^字符集合]”匹配不在指定集合中的任何字符。
select * from TStudent where cardid regexp '^[^1-7]';

八、使用{M}或者{M,N}来指定字符串连续出现的次数

“字符串{n,}”表示至少匹配n次前面的字符。“字符串{n,m}”表示匹配前面的字符串很多于n次,很少于m次。查找×××中出现138而且后面有8位0-9的数字的学生。select * from TStudent where cardid regexp '138[0-9]{15}';

相关文章
相关标签/搜索