DISTINCT 检索不同行
该关键字的作用就是用来去重,可以将你所要展示的数据中完全相同的去重,只展示一个;
LIMIT 限制结果
该关键字的作用就是你限制它返回几条数据,比如你想要获得前面5行的据,就可以使用limit 5,加在sql语句最后面;你也可以指定返回指定位置的数据,LIMIT 5,5表示MySQL返回从行5开始的5行,第一个数为开始位置,第二个数为要检索的行数;此处要注意的是,检索出来的第一行为行0而不是行1;这点和数组很相似,都是在0索引开始储存数据;
ORDER BY 对结果进行排序
ORDER BY 关键字是默认升序排列,要是想要降序排列,就要使用DESC关键字;
注意:这里排序的依据是根据字母顺序来进行排序的,但是对数字也使用;
IN操作符
IN操作符起到的作用和or是一样的;
NOT操作符
它的功能只有一个,就是否定它之后所跟的所有条件;
LIKE操作符
在搜索子句使用通配符,必须使用LIKE操作符
最常用的通配符是百分号(%)。在搜索串中,%表示任何字符出现任意次数。(注意不能匹配NULL)
还有一个有用的通配符就是下划线(_),下划线的用途和%一样,但是下划线只匹配单个字符而不是多个字符。
通配符可以在搜索模式中任意位置使用,并且可以使用多个通配符
与%能够匹配0个字符不一样,_总是匹配一个字符,不能多也不能少。
使用通配符的技巧
1.不要过度使用通配符,如果其他操作符能够达到相同的目的,应该使用其他的通配符;
2.在确实需要使用通配符时,除非绝对有必要,否则不要把他们用在搜索模式的开始处,把通配符置于搜索模式的开始处,搜索起来是最慢的;
3.仔细注意通配符的位置,如果放错地方,就可能不会返回想要的数据;
REGEXP操作符
REGEXP后面跟的东西作为正则表达式处理;
然后[ ]是另一种形式的OR语句,[123]Ton是[1|2|3]Ton的缩写,也可以使用后者。
字符集合也可以被否定,在集合的开始处放一个^即可,因此尽管[123]匹配字符1,2或3,但是[^123]却匹配出这些字符外的任何东西。
然后可以表示查找范围,[0123456789]表示可以查找0~9的所有数字,为了简化,可以用[0-9]表示;不仅只适用于数字,[a-z]匹配任意字母字符。
有的时候想要查找一些特殊字符,这时候就需要使用\\为前导,\\-表示查找-,\\.表示查找 . 。
正则表达式内具有特殊意义的所有字符都必须以这种方式转义;
你可能会需要寻找所有的数,不管数字中包含多少数字,或者你可能想寻找一个单词并且还能够适应一个尾随的s,等等;
拼接字段
Concat操作符
在MySQL的select语句里面,可使用Concat( )这个函数来实现拼接两个列。
注意:
多数DBMS使用+或||来实现拼接,MySQL则使用Concat( )这个函数来实现,当把SQL语句转换成MySQL语句时一定要把这个区别铭记在心。
当你的数据库里面的数据最右边有空格,但是你又不想得到得到这些空格,这可以通过使用MySQL的PTrim()函数来实现,如下所示:
AS操作符
从前面的输出中可以看到,select语句拼接地址字段工作的很好,但此新计算列的名字是什么呢?实际上它没有名字,它只是一个值。如果仅仅只是查看的话没有任何问题,但是如果你要是使用里面的数据的话,就要用AS关键字赋予别名,之后就可以通过别名来进行调用该拼接的数据;
对数据进行计算(可以通过AS命名来直接得到计算后的结果列)
细节:select Now();可以返回当前日期和时间;
函数
大多数SQL实现支持以下类型的函数:
函数例子:
一般,应用程序不使用用来存储日期和时间的格式,因此日期和时间函数总是被用来读取,统计和处理这些值。由于这个原因,日期和时间函数在MySQL语言中具有重要的作用。
小细节,在数据库中存储时间一般都是日期加时间,如下所示:
然而我们查找数据的时候有时只用查找它的日期,这个时候就要用Date( )函数来得到这个日期;
如果要的是日期,请使用Date();如果你想要的仅仅是日期,则使用Data()是一个良好的习惯;
数值处理函数
数值处理函数仅用于处理数值数据,这些函数一般主要用于代数,三角或者几何运算,因此没有串或者日期-时间处理函数的使用那么频繁,但是具有讽刺意义的是,在主要的DBMS的函数中,数值函数是最一致最同意的函数。(用的少却最统一)
聚集函数
我们经常需要汇总数据而不用将它们实际检索出来。为此MySQL提供了专门的函数。使用这些函数,MySQL查询可用于检索数据,以便分析和报表生成,这种类型的检索例子有以下几种:
聚集函数:运行在行组上,计算和返回单个值的函数。
小细节:AVG( )函数在使用时会忽略值为NULL的,而不是看为0来计算;
COUNT( )函数
COUNT( )函数进行计算,可利用COUNT()确定表中行的数目或者符合特定条件的行的数目;
COUNT( )函数有两种使用方式。
这个就是返回demo1表中的行数。
这个就是根据age列的数据来确定行数,这种算法忽略了age为NULL的行;
注意:如果指定列名,这指定列的值为NULL的行会被忽略,但是如果COUNT( )函数中使用的是星号( * ),则不忽略NULL;(我的理解就是 * 就是对所有的列进行检索,因为一行不可能所有的值都为NULL,所以COUNT(*)会得到所有的行数)
DISTINCT关键字
DISTINCT关键字就相当于去重的功能,就是相同的数据就只算它一次
例如下面的例子:
select avg(distinct age) from demo1;
这个在计算demo1中的平均年龄时,就只考虑不相同的数据,出现过的年龄就不会在计算了;
这里用单条SELECT语句执行了四个聚集计算,返回4个值;
小结:聚集函数用来汇总数据,MySQL支持一系列聚集函数,可以用多种方法使用它们以返回所需的结果,这些函数是高效设计的,他们返回结果一般比你在自己的客户机应用程序中计算要快的多。(其实我们可以将所有的数据得到,然后自己在客户端进行计算得到最大值,最小值,平均值等,但是这样的话用的时间会很多,想要节省时间的话,就可以使用聚集函数来计算,这样是很高效的)
分组数据
学习了聚集函数,我们就可以计算指定数据的行数,最大值,最小值等,但是每次只能计算一组,比如说我想知道每个群聊的群聊人数,不使用分组数据的话,就只能使用where来一个群聊一个群聊的查询,但是使用了分组数据之后, 我们就能够一次性查询到所有群聊的人数啥的,大大减少代码量和提高速度;
要用到GROUP BY子句;
上面的SELECT语句指定了两个列,一个是group_id(群id),另一个num_user是计算字段(用COUNT(*)函数建立),GROUP BY子句指示MySQL按group_id排序并且分组数据,这导致对每个group_id而不是整个表计算num_user一次;
除了能用GROUP BY分组数据为,MySQL还允许过滤分组,就是得到满足一些条件的分组,这就要用到HAVING关键字;
这个例子过滤了群聊人数小于4的组;
HAVING和WHERE的差别
这里有另一种理解方法,WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤(在书写时也是WHERE在GROUP BY 的前面,HAVING在后面);
这个例子是先将群成员里面等级等于1的数据过滤掉,然后再过滤群人数小于3的组;
SELECT子句顺序
小结:这里主要学习了如何用SQL聚集函数对数据进行汇总计算,学会了使用GROUP BY子句对数据组进行这些汇总计算,还学会了使用HAVING子句过滤特定的组,还知道了ORDER BY和GROUP BY之间以及WHERE和HAVING之间的差异;
子查询
当我们使用关系表来存储数据时,想要查询数据就会变的麻烦一点,就比如用户表和好友关系表,当我要查询一个用户的所有好友的好友信息时,就要先再关系表里面找到他的好友的id然后根据这个id在用户表中得到该好友的所有信息,这样会比较麻烦,我们可以使用子查询来节省时间和提高效率;
这个例子就是现在关系表里面找到该用户的所有好友id,然后通过这个id在用户表里面查询好友资料;
子查询虽然能够达到这个效果,但是使用子查询并不总是执行这种类型的数据检索的最有效的方法;后面还会学习有关的方法;
SQL最强大的功能之一就是能在数据检索查询的执行中联结表;
为什么要使用关系表?
总之,关系表可以有效低存储和方便的处理,因此,关系数据库的可伸缩性远比非关系数据库要好。
可伸缩性:能够适应不断增加的工作量而不失败。涉及良好的数据库或应用程序称之为可伸缩性好;
这是一个例子,他找出了群号为49289306112的群里面的所有群聊成员;
在使用联结查询的时候,一定要有where语句,如果没有的话就会输出巨多的没用的数据,有了where语句还不行,还要保证where语句的准确性,如果你的where语句不准确的话,不正确的过滤条件将导致MySQL返回不正确的数据;
除了上面的语法,还有一种写法,能够实现一样的功能;
这里与前面的区别就是FROM子句不同,这里,两个表之间的关系是from子句的组成部分,以INNER JOIN指定。在使用这种语法时,联结条件用特定的ON子句而不是WHERE子句给出。传递ON的实际条件与传递给WHERE的相同。
至于这两种语法选择哪一种,ANSI SQL规范首选INNER JOIN语法,此外,尽管使用WHERE子句定义联结的确比较简单,但是使用明确的联结语法能够确保不会忘记联结条件,有时候这样做也能影响性能;
联结多个表
SQL对一条SELECT语句中可以联结的表的数目没有限制。创建联结的基本规则也相同,都是先列出所有表,然后定义表之间的关系;
性能考虑:MySQL在运行时对联结表的处理时非常的耗费资源的,因此不要联结不必要的表,联结的表越多,性能下降越厉害。
在之前的学习中我们学习了子查询,子查询和联结都能达到目的,但是他们两个不是说哪个一定好,这个要看情况而定;
之前学习的AS可以为列创建别名,但是其实AS也能够给表建立别名;
注意:表别名只在查询执行中使用。与列别名不一样,表别名不返回到客户机。
联结使用的某些要点
组合查询就是利用UNION操作符将多条select语句组合成一个结果集
在下面两个基本情况里面要用到组合查询:
在写qq聊天室项目时,我用到了组合查询,因为在好友关系表里面A是B的好友,那么B也是A的好友,所以在查询时,我们即要查看自己在A时有多少个B好友,又要查找自己为B时有多少给A好友;
这个UNION就是查询了存款大于2000和年龄小于19的结果;
UNION使用规则:
小细节:
使用UNION时,它会默认将多条select语句查询到的重复的行去重,所以在使用UNION时,重复的行会被去除,但是我们需要的话,也可以使用UNION ALL来获得所有的匹配行;
当我们想要对组合查询结果进行排序的时候,只能使用一条ORDER BY子句,它必须出现在最后一条select语句之后,对于结果集,不存在用一种方式排序一部分,而又用另一种方式排序宁一部分的情况,因此不允许使用多条ORDER BY语句;
上面的例子中的组合查询使用的均是demo1表,但是UNION可以用于组合查询不同的表;
并非所有的引擎都支持全文本搜索,两个最常用的引擎为MyISAM和InnoDB,前者支持全文本搜索,而后者不支持。
在之前我们学习了使用LIKE和通配符来搜索文本,还有REGEXP操作符后面加正则表达式来搜索行;虽然这些搜索机制很有用,但是存在几个重要的限制:
首先,我们先建一个表:
这里FULLTEXT(note_text) 表示将note_text设置为全文本查找的字段;
然后就是插入数据:
然后首先测试like模糊查询
查询结果分析:应为like模糊查询是在整个数据中查看有没有包含'fiction'这个单词的,如果有就过滤出来,而在我插入的数据中,1和5是有的;
然后再是全文本搜索
再测试全文本搜索-布尔文本搜索
在全文本搜索中常用的布尔运算符
使用扩展查询
这个会根据包含fiction的两条行中的数据中的其他单词来对其他行进行匹配,相当与找到了正确答案还要找与正确答案类似的答案;
全文本搜索-显示排名字段,按照匹配度由高到低排序
细节:Match( )和Against( )出现的位置对结果的影响较大,当Match( )和Against( )出现在where子句中时,只会返回匹配到的行,但是如果Match( )和Against( )出现在SELECT中的话,就会使得所有的行全部被返回,Match( )和Against( )用来建立一个计算列(别名为rank),此列包含全文本搜索计算出的等级值。等级由MySQL根据行中词的数目,唯一词的数目,整个索引中词的总数以及包含该词的行的数目计算出来,并且这个值还与唯一词所处的位置有关,唯一词靠前的值较高,靠后的值较低。