使用MySQL
选择数据库
如果需要使用某个数据库下面的表,那么我们起码得知道我们都有哪些可以使用的数据库。所以我们通过 show databases; 来展示有哪些可用的数据库。
当我们得知有哪些可用的数据库之后,我们将
使用 use database_name; 来使用database_name这个数据库了。然后我们将可以使用这个数据库的表了。
了解数据库和表
- show databases; 显示可用的数据库列表
- show tables; 显示当前在使用的数据库有哪些表
- show columns from table_name; 显示当前这个表名每行的名字、数据类型、默认值、是否为NULL、键值以及其他。这行代码可以用describe
table_name; 来代替,两者的效果是相同的。
- show create database database_name; 展示创建database_name这个数据库的MySQL语句。
-
- show create table table_name; 展示创建table_name这张表的MySQL语句.
检索数据
select 语句的用途示从一个或多个表中检索信息.
语法:
- select xxx from table_name; 表示从table_name中展示xxx这一列的信息.
值得注意的,如果没有明确排序查询结果(如果需要明确排序的话,还需要有order by子句),那么通过select语句返回的数据顺序并没有特定的意义,返回数据的顺序可能示数据被添加到表中的顺序,也可能不是,只要返回相同的数目的行,就是正常的。
- SELECT xxx1,xxx2,xxx3 …,xxxn from table_name; 获取table_name中xxx1,xxx2,xxx3,…xxxn多列的信息。注意,每个列都需要用逗号分割开来,但是最后一个列不需要加逗号,否则就会出现错误。
如果要获取table_name中的所有信息,那么可以直接使用SELECT * from table_name; 获取table_name这个表的所有列的信息.
- SELECT DISTINCE xxx from table_name; 获取table_name这张表中不同的xxx值,如果在table_name中含有重复值,那么最后显示的只有一个。(DISTINCE(distinct不同的)实现了这个效果)
对于DISTINCT这个关键字,有一点需要提的是,它修饰的是跟在它后面的列这个整体,因此如果DISTINCT后面中有多个列,不要认为他只是修饰紧跟在他后面的第一个列,而应该是跟在他后面的列形成的整体。所以最后得到的是应该是table_name中多个列形成的整体的不同的值。
即SELECT DISTINCT name,email from student; 是获取name + email这个整体不相同的值,而不是获取不同的名字+email的值。
- SELECT xxx FROM table_name LIMIT n; 返回table_name中不多于n条xxx的数据。之所以是不多于,是因为如果table_name中的数据不多于n行,那么这时候就会返回talbe_name中的所有数据。如果在LIMIT后面只有一个值,表示从第一行开始的,也就是行0,给出的数字n就是需要返回的行数。
- SELECT xxx FROM table_name LIMIT m offset n; 表示从行n开始检索,返回m条数据.当然这条语句也可以是
SELECT xxx FROM table_name LIMIT n,m
;但是这样的语句可能会混淆,如果一不小心记错了语法不知道是从行n开始检索,返回m条数据,还是从行m开始检索,返回n条数据,所以如果需要从行n开始检索,返回m条数据,建议使用LIMIT m OFFSET n,避免往后的学习出现大错。
如果LIMIT后面又两个值(即LIMIT n,m),那么第一个值n表示行号从行n开始检索,返回m行数据。
对于上面的DISTINCT例子可能不是很清晰,我们在来开一下下面的例子:
所以根据上面的例子,我们将得到:如果含有DISTINCT 和LIMIT的话,那么是在DISTINCT返回的数据中进行LIMIT的,而不是在LIMIT返回的数据中查找DISTINCT的数据。
排序检索数据
我们经过上面的学习,可以知道SELECT返回的某个数据库的单个列,他的输出没有特定的顺序,但是如果我们要求将输出有序,需要利用ORDER BY子句。
-
SELECT xxx FROM table_name ORDER BY yyy; 从table_name中返回xxx列对应的值,并且这些值是按照yyy升序进行排序的。
-
SELECT xxx FROM table_name ORDER BY yyy1,yyy2,…,yyyn; 从table_name中返回xxx列对应的值,并且这些值是按照yyy1,yyy2,…,yyyn进行排序的,即如果yyy1不相同,就按照yyy1升序排序,否则依据yyy2升序排序,否则,如果yyy2相同,就按照yyy3升序排序,以此类推。
-
SELECT xxx FROM table_name ORDER BY yyy DESC; 从table_name中返回xxx列对应的值,并且这些值是按照yyy降序进行排序的,即在对应的列的后面添加DESC关键词。如果有多个列,就像上面的yyy1,yyy2,…yyyn,如果要求多个列都是按照降序排序的话,那么需要在每个对应的列中添加DESC;
- SELECT xxx FROM table_name ORDER BY yyy LIMIT 1;利用ORDER BY 和 LIMIT将可以得到表中行的最值,只要从行0开始检索,获取1条数据即可得到最值。 但是值得注意的是,再给出ORDER BY字句时,需要保证ORDER BY 放在了FROM的后面,放在LIMIT的前面.
值得注意的是,如果在table_name中xxx具有重复,假设xxx按照升序排在第一个位置,那么SELECT xxx FROM table_name ORDER BY yyy LIMIT 1; 返回的就是最后一个xxx的数据.
如果我们不是要求最值,而是要求第k大之类的怎么办呢?
由于是第几大的数据只有一条数据,所以m = 1,所以我们只要知道了n的位置,我们就可以返回第几大的数据了。还记得我们行0表示的是第一行数据,如果表中的数据是按照降序的话,那么他就是第一大,以此类推,行1就是第二大的。所以n的值就是行k - 1.所以只要利用LIMIT 1 OFFSET K - 1。
但是前提是有序,并且行0就是第一大才可以,所以需要调用ORDER BY子句,并且排序是降序排序的得到的才是第几大。
同时,如果值相同的话,那么同样在同一个等级,比如行0的值出现了多个,那么这多个值同样是第一大的情况下,那么还需要利用DISTINC关键字才可以。 上面就已经说过了SELECT DISTINCT XXX FROM table_name ORDER BY yyy LIMIT m OFFSET n是在xxx不同的表中进行排序之后检索的。
关于这个例子,我们可以来看一下这个题目就知道了:第二高的薪水
过滤数据
在SELECT语句中,数据根据WHERE子句中指定的搜索条件进行过滤。WHERE子句在表明FROM的后面。
- SELECT xxx FROM table_name WHERE yyy;
从而过滤掉了表中没有符合WHERE子句的数据,最后输出的数据都是符合WHERE子句的条件。
如果有多个条件需要判断的时候,则需要用AND或者OR进行拼接。
WHERE子句的操作符:
但是在利用AND 与 OR的时候需要注意一下优先级的问题,因为AND的优先级比OR的高,所以一旦不注意两者的优先级,就会可能导致一些错误。所以为了避免这种错误,用圆括号将对应的条件括起来。
除了上面几个操作符之外,还有几个相对重要的操作符需要认识:
-
IN操作符:
-
NOT操作符:否定紧跟在NOT后面的第一个条件的关键字。所以NOT后面有多个条件的关键字,并且需要使用多个否定的时候,需要在对应的条件关键字前面加上NOT才可以。
age not between 20 and 24 and
salary between 30000 and 50000;
– 表示的是年龄age不在[20,24]范围
,并且salary在[30000,50000]的人的
所有数据
age not between 20 and 24 and
salary not between 30000 and 50000
; – 表示age不在[20,24]并且salary
不在[30000,50000]的人的所有数据
在SELECT语句中有一个特殊的WHERE子句,用来检查具有NULL值得列,这个WHERE子句就是
IS NULL子句。对应的形式为:
- SELECT xxx FROM table_name WHERE yyy IS NULL; 表示的是需要获取table_name中yyy是 NULL的对应的xxx值。
- SELECT xxx FROM table_name WHERE yyy IS NOT NULL; 表示的是需要获取table_name中yyy不是 NULL的对应的xxx值。
同时需要注意的是,如果在WHERE子句中同时含有ORDER BY子句、LIMIT子句,那么对应的顺序是怎样的呢?我们上面已经知道了,ORDER BY 需要放在FROM的后面,LIMIT的前面,所以只要知道ORDER BY放在WHERE哪里即可。通过学习,可以知道,ORDER BY是放在WHERE 的后面的。
所以对应的形式为:
SELECT xxx FROM table_name
WHERE yyy – 如果有多个条件需要进行过滤,那么需要使用AND 或者OR进行过滤
ORDER BY zzz – 根据zzz进行升序排序的,如果有多个列,那么每个列需要用逗号隔开,最后一列不需要,如果要求某个列降序,那么需要在这个列的后面添加DESC关键词
LIMIT m; – 从行0开始检索,返回m行数据,如果是需要指定从行n开始检索,那么需要变成LIMIT m OFFSET n
用通配符进行过滤
为在搜索子句中使用通配符,必须使用LIKE操作符,LIKE指示MySQL,后跟的搜索模式利用通配符匹配而不是直接相等匹配进行比较。
- % 通配符:表示任意字符出现任意次。
- _(下划线)通配符:表示匹配单一的任意字符。
用正则表达式进行搜索
使用正则表达式,需要使用的是关键字REGEXP,而不再是LIKE。
简单来说就是REGEXP是从串的任意位置进行匹配的,而LIKE是从串的开头进行匹配的。
那么REGEXP能不能用来匹配整个列值呢?即从串的开头进行匹配,一直到结尾。答案是肯定的,这里就需要考虑到了定位符了。
所以如果在串的前面添加^,后面添加$,REGEXP即可实现LIKE的效果,匹配整个列值。
如果需要搜索两个串之一,则需要使用|
,如下图:
但是xxx | yyy | zzz 这样写存在这风险,因为一旦在zzz的后面还有一些字符串ttt,即xxx|yyy|zzz ttt,那么这时候不再是我们想的要么是匹配xxx ttt字符串 ,要么是匹配yyy ttt字符串,要么是匹配zzz ttt字符串,而是要么是匹配xxx,要么是匹配yyy字符串,要么是匹配zzz ttt。这就是出现错误的结果。所以需要用[ ]
将xxx|yyy|zzz括起来,才可以实现我们最初的目的,即[xxx|yyy|zzz] ttt才是我们最初的目的,要么匹配xxx ttt字符串,要么匹配yyy ttt字符串,要么匹配zzz ttt字符串。
所以[ ]
用来匹配中括号内特定的一个字符。
需要将集合[ ]
中的字符串放在开头进行匹配的时候,需要将^
放在中括号的前面即可。
但是如果想要实现不匹配[ ]
的字符的时候,在中括号里面添加^
,运行时,发现所有的数据都会出现,这是为什么呢?:
可能有人会说,[ ]
的意义,他表示能够匹配中括号中的任意一个字符,例如[123] 也可以写成[1 | 2 | 3],所以如果在中括号中加^
的话,那么表示不会匹配中括号的任意一个字符,但是由于是 | 的原因,并不能实现我们真正的意图。因为[^123]就相当于了[^1 | ^2 | ^3],此时再次相当于 xxx NOT REGEXP “1” OR xxx NOT REGEXP “2” OR xxx NOT REGEXP “3”.而OR的作用是只要其中一个条件满足即可。所以尽管当前有一个字符是1,但是由于没有匹配到2,所以同样会输出.所以上面的例子中才会输出全部的数据。
但事实证明了,[^123] 并没有等同于 xxx NOT REGEXP “1” OR xxx NOT REGEXP “2” OR xxx NOT REGEXP “3”,所以关于[^123]为什么输出得到的是全部数据,还请大佬指教.
如果希望不匹配[ ] 中的所有字符,那么使用的是NOT REGEXP “[ XXX]”,这样才可以实现真正不匹配[ ]中的任意一个字符。
当然如果[ ]
中的字符可以是连续的,那么我们将可以用-
进行连接,比如[012345]可以写成[0-5]。
如果需要匹配到特殊的字符的话,那么需要进行转移。比如,我们希望匹配 . ,那么应该"\."即可.
如果需要匹配多个实例的时候,那么可以使用下面的重复元字符:
创建计算字段
在MySQL中,使用Concat()函数进行拼接。
然而使用Concat函数有一个奇怪的现象,就是,如果函数中的参数中有一个为NULL,最后得到的还是NULL。
那么应该怎样解决这样的问题呢?可以使用IFNULL函数,将有可能为NULL值得那一列调用IFNULL函数即可,如果是,就将其改成空字符串或其他便于说明这个值为NULL的值.
但是我们看到使用Concat返回的数据,它的名字是Concat(name,"(",role,")"),这样的话过于难看,所以有没有办法修改它的名字呢?当然可以的,我们可以使用关键字AS来取别名.
计算字段的另一常见用途是对检索出的数据进行算数计算。