本篇是基础的SQL语法学习,学完了这些内容就可以说掌握了SQL语句。首先通过MySQL导入示例数据库,至于使用cmd还是navicat根据自身情况来安排。个人建议是利用navicat的可视化视图展示,同时运用SQL语言进行编写操作。这样做,一方面是因为可视化操作界面不会令你感到陌生而减少学习新知识的兴趣,另一方面通过自己动手编写SQL语言能让你更快地上手这门语言,毕竟“好记性不如烂笔头”;另外随着数据量的增多,你会越来越多地发现运用语言编写操作数据库的好处。
*导入示例数据库
https://www.yiibai.com/mysql/how-to-load-sample-database-into-mysql-database-server.html
如果你使用的是navicat可以参考下面的资料便于你更快地上手MySQL。
*Mysql可视化工具Navicat的基本使用
https://www.jianshu.com/p/6b3740ab112e
SQL是什么?MySQL是什么?
在第一篇MySQL学习中我们了解了一些关于数据库的基础知识。至于SQL是什么,你可以将其简单理解为跟数据库打交道所使用的语言。
SQL代表结构化查询语言(Structured Query Language)。SQL是用于访问数据库的标准化语言。
SQL包含三个部分:
1.数据定义语言包含定义数据库及其对象的语句,例如表,视图,触发器,存储过程等。
2.数据操作语言包含允许您更新和查询数据的语句。
3.数据控制语言允许授予用户权限访问数据库中特定数据的权限。
换句话说,根据用途不同SQL语言分为定义、操作与控制三种。SQL语句是由简单的英语单词构成,这些单词我们称之为关键字。每个SQL语句都是由一个或多个关键字构成的。作为SQL组成部分的保留字,关键字不能用作表或列的名字,而且更加重要的是,要理解SQL是一种语言而不是一个应用程序。所以具体如何写SQL语句并显示语句输出,是随不同的应用程序而变化的。就好比同样是使用英语,英式英语与美式英语在许多语法习惯和词句组合上还是存在区别的。
了解了什么是SQL语言,再来看下关于MySQL的概念。我们知道MySQL是市面上使用SQL语言的流行数据库中的一种。MySQL是一个数据库管理系统,也是一个关系数据库。它是由Oracle支持的开源软件。与其他数据库软件(如Oracle,SQL Server)相比,MySQL非常容易学习和掌握。
MySQL可以在各种平台上运行UNIX,Linux,Windows等。可以将其安装在服务器甚至桌面系统上。 此外,MySQL是可靠,可扩展和快速的,常用于开发网站或Web应用程序,当然还有轻量级的数据挖掘与分析。
好了,了解完上面这些你必须知晓的概念,我们将正式进入SQL语言的学习。首先来看下“大名鼎鼎”的SELECT语句。
查询语句SELECT FROM
最经常使用的SQL语句大概就是select语句了,它的用途是从一个或多个表中检索信息。
- 语句解释
使用SELECT语句需要注意以下几点:
1.必须至少给出两条信息——想选择什么以及从什么地方选择;
2.多条SQL语句必须以分好( ; )分割;
3.SQL语句不区分大小写,所以SELECT与select是相同的,一般关键字使用大写,而列名和表名使用小写;
4.在 处理SQL语句时,其中所有空格都被忽略;
5.在检索多个列时,要在列名之间加上逗号,但最后一列不加否则会报错;
6.一般而言,除非你确实需要表中的每一列,否则最好别使用通配符*
下面你可以在navicat中使用新建查询尝试编写一些简单的SELECT的语句,比如:
SELECT customers.customerName FROM customers ;
SELECT * FROM customers
- 去重语句
去重的办法是使用DISTINCT,这个英文单词的意思是“有区别的、独特的”,它表示数据库只返回不同的值。需要在注意的是使用DISTINCT关键字,必须直接放在列名的前面,而且DISTINCT关键字作用于所有的列,换句话说就是不能部分使用DISTINCT。
SELECT DISTINCT
customers.contactFirstName
from customers
- 前N个语句
有时候你想取数据当中的一部分行,在不同的数据库当中这一SQL实现并不相同,这里我们只看在MySQL中如何实现,至于其他数据库如果有兴趣的话可以自行搜索解决。
在MySQL中提取前N个语句使用关键词LIMIT,比如
SELECT DISTINCT
customers.contactFirstName
from customers
LIMIT 5
意思就是在上面例子的基础上只取前5行,而非全部。有时候你并不想从第0行开始(这里需要注意的是,在MySQL数据库中行数是从0开始计数,所以第1行对应到表格中实际上是第2行数据),那么可以使用关键OFFSET。
SELECT DISTINCT
customers.contactFirstName
FROM
customers
LIMIT 5 OFFSET 3
意思是从表格的第4行开始,取前5行,结果显示取出从Janine至Roland 5行数据。
另外MySQL还支持简化版的LIMITOFFSET语句,即LIMIT 3,5 ,这跟上面例子中 LIMIT 5 OFFSET 3 的结果是一样的。注意顺序变化,简化版是先确定从哪一行开始索引然后再确定提取几行数据。
- CASE…END判断语句
CASE语句是计算条件列表并返回多个可能的结果表达式之一。完整的句式应该是:
CASE…
WHEN1…THEN1…
WHEN2…THEN2…
…
WHENn…THENn…
ELSE…
END
CASE表达式有两种格式:
1.简单的CASE表达式将表达式与一组简单表达式进行比较以确定结果。
2.搜索到的CASE表达式计算一组布尔表达式以确定结果。
我们还是来看具体的示例说明。
SELECT
count(customerName),
CASE country
WHEN "France" THEN
"EU"
WHEN "USA" THEN
"NA"
WHEN "Spain" THEN
"EU"
ELSE
NULL
END
FROM
customers
GROUP BY
CASE country
WHEN "France" THEN
"EU"
WHEN "USA" THEN
"NA"
WHEN "Spain" THEN
"EU"
ELSE
NULL
END
这段代码是提取customers表中作为欧洲的法国人与西班牙人和作为北美洲的美国人的人数各是多少,统计结果如下:
EU 19
NA 36
Null 67
个人将CASE表达式对比Excel中sumifs与sumproduct函数来理解,也就是多条件求和。如果看完以后感到有些费劲,没有关系,这里只是通过示例展示CASE语句的用法,当你在现实生活遇到需要CASE表达式来解决的问题时再去慢慢摸索也不迟。
筛选语句WHERE
在实际工作当中面对大量数据很少需要检索表中所有行的,通常只会根据需求提出表数据的子集。那么需求就是你的搜索条件,也称为过滤条件,更通俗地理解就是筛选。在SELECT语句中,数据根据WHERE子句中指定的搜索条件进行过滤。一般WHERE子句在FROM子句后给出。下面罗列一些常用的WHERE子句操作符:
操作符 | 说明 |
---|---|
= | 等于 |
<> | 不等于 |
!= | 不等于 |
< | 小于 |
<= | 小于等于 |
!< | 不小于 |
> | 大于 |
>= | 大于等于 |
!> | 不大于 |
BETWEEN | 在指定的两个值之间 |
IS NULL | 为NULL的值 |
AND | 多条件过滤 |
OR | 或条件过滤 |
IN | 与OR类似,指定匹配值 |
NOT | 逆条件筛选 |
WHERE子句相对来说容易理解一些,你可以结合操作符自行摸索,这里就不给出具体示例了。
分组语句GROUP BY
分组使用SELECT语句的GROUPBY子句建立,当然这同样是一种对数据的过滤方式,我们先来看一个示例:
SELECT
country,
count(*) AS Num
FROM
customers
GROUP BY
country
LIMIT 5
输出结果:
country Num
France 12
USA 36
Australia 5
Norway 3
Poland 1
语句解释:从customers表中统计各个国家的人数并提取前5行进行显示。
使用GROUPBY子句需要注意以下几点:
1.GROUPBY可以对分组进行嵌套;
2.GROUPBY列出的每一列必须是检索列或有效表达式(比如上例中的count(*));
3.GROUPBY列不允许带有 长度可变的数据类型,如文本或者备注型字段
4.NULL值将作为一个分组返回,若是多行则分为一组;
5.GROUPBY子句必须出现在WHERE子句之后,ORDERBY子句之前。
另外补充一个知识点。SQL除了可以分组数据外还允许过滤分组。你可能会第一时间想到上面刚刚介绍的WHERE,不过WHERE过滤指定的是行而不是分组。这里就需要引入一个新的关键字HAVING子句。在大部分时候HAVING可以替代WHERE,两者的唯一区别是WHERE过滤行,而HAVING过滤分组。使用HAVING时应该结合GROUPBY子句,而WHERE子句用于标准的行级过滤。
我们在上面的例子最后加一句“LIMIT 5”换成“HAVING COUNT(*) >=10 ”后,可以得到如下结果:
country Num
France 12
USA 36
Germany 13
排序语句ORDER BY
顾名思义ORDERBY子句是用来对数据进行排序的,经常与GROUPBY子句结合使用,但两者非常不同。
ORDER BY | GROUP BY |
---|---|
对产生的输出排序 | 对行分组,但输出可能不是分组的顺序 |
任意列都可以使用(甚至非选择的列也可以使用) | 只可能使用选择列或表达式列,而且必须使用每个选择列表示式 |
不一定需要 | 如果与聚集函数一起使用列(或表达式),则必须使用) |
一般使用GROUPBY子句时,应该也给出ORDERBY子句,这是保证数据正确排序的唯一方法,因为很多时候GROUPBY在排序数据方面很不靠谱。结合示例仔细体会。
SELECT
country,
count(*) AS Num
FROM
customers
GROUP BY
country
HAVING
COUNT(*) > 10
ORDER BY
customerName;
输出结果:
country Num
France 12
Germany 13
USA 36
以上就是对SELECT语法中主要子句的介绍。这里做个小结并补充一个非常重要的知识点,即SELECT语句中各个子句使用时必须遵循一定次序:
序号 | 子句 | 说明 | 是否必须使用 |
---|---|---|---|
1 | SELECT | 要返回的列表或 表达式 | 是 |
2 | FROM | 从中检索数据的表 | 仅在从表选择数据时使用 |
3 | WHERE | 行级过滤 | 否 |
4 | GROUP BY | 分组说明 | 仅在按组计算聚集时使用 |
5 | HAVING | 组级过滤 | 否 |
6 | ORDER BY | 输出排列顺序 | 否 |
函数
平时工作经常操作Excel的朋友对函数应该不会陌生,在SQL语言中同样可以用函数来处理数据。函数一般是在数据上执行,为数据的转换与处理提供方便。但与在Excel中使用函数所不同的是,在不同的数据库里,都有各不相同的特定函数,主要少数几个函数被所有主要的数据库管理系统共同支持。这意味着你在A数据库里写的带有函数的SQL代码,换到B数据库中运行可能就会报错。与SQL语句不一样,SQL函数不是可移植的。
这个知识点目前以了解为主,你也不用纠结要不要用函数,个人建议是根据自身情况决定,如果你平时工作使用SQL语言且技术层面的交流也局限于公司内部,那放心大胆地使用函数是没有问题的;但如果考虑到代码的可移植性,建议还是尽量少用(尤其是特定数据库当中的特定函数),即便要用也要做好代码注释,以便以后你或者别人能确切地指导所编写SQL代码的含义。
不过,有些类型的函数是大多数SQL实现支持的,比如:
1.用于处理文本字符串的文本函数,如删除或填充值、转换值为大写或小写;
2.用于在数值数据上进行算数操作的数值函数,如返回绝对值、进行代数运算;
3.用于处理日期和时间值并从这些值中提取特定成分的日期和时间函数,如返回两个日期之差、检查日期有效性;
4.返回DBMS(数据库管理系统)使用的特殊信息的系统函数,如返回用户登录信息。
下面对文本处理函数、日期时间处理函数、数值处理函数以及聚集函数分别进行简单介绍。
- 文本处理函数
有时候出于实际需要我们要将列值右边的空格去掉,则使用RTRIM()函数;将所有字符串转换为大写,则使用UPPER()。下面是一些常用的文本处理函数:
函数 | 说明 |
---|---|
LEFT() | 返回字符串左边的字符 |
RIGHT() | 返回字符串右边的字符 |
LENGTH()或LEN() | 返回字符串的长度 |
LOWER() | 将字符串转换为小写 |
UPPER() | 将字符串转换为大写 |
LTRIM() | 去掉字符串左边的空格 |
RTRIM() | 去掉字符串右边的空格 |
SOUNDEX() | 返回字符串的SOUNDEX值 |
注:关于SOUNDEX是一个将任何文本串转换为描述其语言表示的字母数字模式的算法,类似于HASH(),虽然SOUNDEX不是SQL概念,但多数DBMS都提供对SOUNDEX的支持。
- 日期时间处理函数
关于日期时间处理函数,每种DBMS都有自己特殊形式。像本人所在公司数据库布局在HADOOP上,使用最频繁的就是从数据库当中提取前一天的相关数据信息,这时候就要用到自造的时间处理函数dateif进行WHERE筛选。日期时间处理函数在不同数据库之间可以说是移植性最差的。这里就不单独罗列了,如果有时间与兴趣的朋友可以参考下面资料进行查询。
*MySQL日期时间处理函数
https://www.jianshu.com/p/22eb5c6c1d67 - 数值处理函数
在《SQL必知必会》中作者不无调侃地说道:“具有讽刺意味的是,在主要DBMS的函数中,数值函数是最一致、最统一的函数。”不过根据日常经验,我们也知道,数值处理函数显然没有处理文本与日期时间那么频繁。这就让人有点啼笑皆非了。下面列出一些常用的数值处理函数以供参考。
函数 | 说明 |
---|---|
ABS() | 返回一个数的绝对值 |
COS() | 返回一个角度的余弦 |
EXP() | 返回一个数的指数值 |
PI() | 返回圆周率 |
SIN() | 返回一个角度的正弦 |
SQRT() | 返回一个数的平方根 |
TAN() | 返回一个角度的正切 |
- 聚集函数
什么是聚集函数?简单理解就是对数据进行聚集操作后直接展示结果,而无需看到原数据,比如求和、求平均等。在日常工作中使用聚集函数可用于检索数据以便分析和报表生成。
聚集函数对某些行运行的函数,计算并返回一个值。
SQL语法中一共有5个聚集函数,具体用法说明可以查看下表:
函数 | 说明 |
---|---|
AVG() | 返回某列的平均值 |
COUNT() | 返回某列的行数 |
MAX() | 返回某列的最大值 |
MIN() | 返回某列的最小值 |
SUM() | 返回某列值之数 |
熟悉Excel操作的朋友对此一定是驾轻就熟,这里仅对一些注意事项做些提示:
1.AVG()只用于单个列,且忽略NULL值;
2.COUNT()会忽略NULL值,但COUNT(*)不忽略NULL值;
3.在用于文本数据时,MAX()返回按该列排序后的最后一行,且忽略NULL行;
4.MIX()正好与MAX()相反;
5.SUM()忽略NULL行;
6.所有聚集函数都可用来在还行多个列上的计算;
7.聚集不同值是可使用DISTINCT子句。
下面结合一个综合示例进行理解:
SELECT
count(*) AS Num_item,
MIN(creditLimit) AS creditLimit_min
MAX(creditLimit) AS creditLimit_max
AVG(creditLimit) AS creditLimit_avg
FROM customers
SQL注释
有些编程基础的朋友对注释不会陌生,没有编程经验也不用担心。注释简单说就对你写的代码进行简明扼要的说明,这些代码是什么以及它们用来做什么。在SQL语法中注释分为单行与多行注释两种,其中单行注释可以使用–两个连字符或#嵌在行内,多行使用从 /* 开始,到 */结束,这之间的内容都是注释。拿我们上面的示例具体演示如下:
SELECT -- 这是第一行(注意在连字符-- 后面有个空格)
country,
count(*) AS Num
# 这是一条注释
FROM
customers
GROUP BY
country
/*通过HAVING子句
对有10人以上客户的国家进行统计 */
HAVING
COUNT(*) > 10
ORDER BY
customerName;
对比注释前后会发现结果是一致的。
SQL代码规范
规范的SQL代码书写格式有益于自己检查与他人阅读,关于这一点很多人应该感同身受。不过实话说,平时自己写SQL代码多是“不问过程、只看结果”,但是如果拿出来供他人阅读还是要做些许处理,比如上面示例当中的代码都是经过navicat的SQL格式美化以后的结果,这也是使用辅助工具的好处。个人理解,SQL代码规范是关于书写SQL代码的一般约定和经验总结,从可移植性与良好使用习惯角度来看,是非常有必要做些了解的。这里给出一篇参考材料,有兴趣的朋友可以自行查阅了解。
*MySQL 规范手册
https://blog.csdn.net/timchen525/article/details/79954434