mysql三范式:
第一范式(确保每列保持原子性)【属性不可分】
第二范式(确保表中的每列都和主键相关)【符合第一范式,同时非主属性完全依赖于主键】
第三范式(确保每列都和主键列直接相关,而不是间接相关)【符合2NF,并且消除传递依赖】

前言

数据库基本查询语句语法如下:

SELECT  列名1...列名n                         

FROM 表名      #选定查找列来自的什么表

[  WHERE 查询条件   ]    #限制查询条件,如果没有就查询所有的行

[ GROUP BY     列名1...列名n   ] #对查询进行分组

[  HAVING  条件 ]    #过滤分组条件

[  ORDER BY    列名1...列名n    [  ASC  |  DESC  ]   ]  #限制查询行数的排列,默认是ASC:正序排列

[  LIMIT  [ 位移偏移量 , ] 行数  ]    #限制查询的行数
1、检索不同的值distinct

在这里插入图片描述
SELECT 语句返回所有匹配的行。但是,如果你不希望每个值每次都出现,该怎么办呢?

比如我想获取age中所有不重复的年龄,做法如下:

select distinct age from person

在这里插入图片描述

注意:DISTINCT关键字只能在第一个字段前,否则报错。

DISTINCT 关键字作用于所有的列,不仅仅是跟在其后的那一列。除非指定的两列完全相同,否则所有的行都会被检索出来。

select distinct name,age from person

在这里插入图片描述

2、限制查询行数

SELECT 语句返回指定表中所有匹配的行,很可能是每一行。如果你只想返回第一行或者一定数量的行,该怎么办呢?这是可行的,然而遗憾的是,各种数据库中的这一 SQL 实现并不相同。本文以MySQL为例子

语法:LIMIT  [ 指定从哪行开始,初始是0 ] 要返回的行数

在这里插入图片描述
案例:返回小明到曹操的数据

select id ,name,age from person limit 1,4

在这里插入图片描述

3、排序
语法:ORDER BY    列名1...列名n    [  ASC  |  DESC  ]   ]  #限制查询行数的排列,默认是ASC:正序排列

问题1、desc和asc有什么区别

用 DESC 表示按bai倒序排序(即:从大到小排序) —降序排列
用 ACS 表示按正序排序(即:从小到大排序)—升序排列

4、where字句

1、数学操作符说明

操作符              说明
=	                等于	
>	                大于
< >	               不等于	
>=	               大于等于
!=	               不等于	
!>	               不大于
<	                小于	
BETWEEN	          在指定的两个值之间
<=	               小于等于	
IS NULLNULL!<	                不小于	
is not null       不为NULL

在这里插入图片描述
案例:查询年龄在30到50的人

select id ,name,age from person where age between 30 and 50

在这里插入图片描述

2、逻辑操作符说明

and    用来指示检索满足所有给定条件的行
OR     用来表示检索匹配任一给定条件的行
IN     操作符用来指定条件范围,范围中的每个条件都可以进行匹配
NOT    用来否定其后条件的关键字

任何时候使用具有 AND 和 OR 操作符的 WHERE 子句,都应该使用圆括号明确地分组操作符。不要过分依赖默认求值顺序,即使它确实如你希望的那样。使用圆括号没有什么坏处,它能消除歧义

为什么使用 NOT?简单的 WHERE 子句,使用 NOT 确实没有什么优势。但在更复杂的子句中,NOT 是非常有用的。例如,在与 IN 操作符联合使用时,NOT 可以非常简单地找出与条件列表不匹配的行。

3、通配符

其操作符是like

最常使用的通配符是百分号(%),在搜索串中,%表示任何字符出现任意次数。例如,为了找出所有以词 Fish 起头的产品,可发布以下 SELECT 语句

SELECT * FROM Products WHERE prod_name LIKE 'Fish%';

Fish 起头的词。%告诉 DBMS 接受 Fish 之后的任意字符,不管它有多少

通配符%看起来像是可以匹配任何东西,但有个例外,这就是 NULL。子句 WHERE prod_name LIKE '%'不会匹配产品名称为 NULL 的

根据 DBMS 的不同及其配置,搜索可以是区分大小写的。如果区分大小写,则’fish%'与 Fish bean bag toy 就不匹配。

另一个有用的通配符是下划线(_)。下划线的用途与%一样,但它只匹配单个字符,而不是多个字符。
在这里插入图片描述

select * from person where name_en like 'caoca_'

在这里插入图片描述

方括号([])通配符用来指定一个字符集,它必须匹配指定位置(通配符的位置)的一个字符

在这里插入代码片
5、分组数据

在这里插入图片描述
数据分组

分组是使用 SELECT 语句的 GROUP BY 子句建立的。理解分组的最好办法是看一个例子:查询各个年龄的人数

select age,count(1) from person group by age

在这里插入图片描述
上面的 SELECT 语句指定了两个列:age 是年龄, count(1) 为计算字段(用 COUNT(*)函数建立)。GROUP BY 子句指示DBMS 按 age 排序并分组数据。这就会对每个 age 而不是整个表计算 一次。从输出中可以看到,表中有4个年龄,10岁,29岁和50岁的各有 1个人,而30岁有3个人。

因为使用了 GROUP BY,就不必指定要计算和估值的每个组了。系统会自动完成。GROUP BY 子句指示 DBMS 分组数据,然后对每个组而不是整个结果集进行聚集。

在使用 GROUP BY 子句前,需要知道一些重要的规定

GROUP BY 子句可以包含任意数目的列,因而可以对分组进行嵌套, 更细致地进行数据分组。

如果在 GROUP BY 子句中嵌套了分组,数据将在最后指定的分组上进行汇总。换句话说,在建立分组时,指定的所有列都一起计算(所以不能从个别的列取回数据)。

GROUP BY 子句中列出的每一列都必须是检索列或有效的表达式(但不能是聚集函数)。如果在 SELECT 中使用表达式,则必须在
GROUP BY 子句中指定相同的表达式。不能使用别名。

大多数 SQL 实现不允许 GROUP BY 列带有长度可变的数据类型(如文本或备注型字段)。

除聚集计算语句外,SELECT 语句中的每一列都必须在 GROUP BY 子句中给出。

如果分组列中包含具有 NULL 值的行,则 NULL 将作为一个分组返回。如果列中有多行 NULL 值,它们将分为一组。
GROUP BY 子句必须出现在 WHERE 子句之后,ORDER BY 子句之前

过滤分组

除了能用 GROUP BY 分组数据外,SQL 还允许过滤分组,规定包括哪些分组,排除哪些分组。例如,你可能想要列出人数大于1的年龄。为此,必须基于完整的分组而不是个别的行进行过滤。

我们已经看到了 WHERE 子句的作用。但是,在这个例子中 WHERE 不能完成任务,因为 WHERE 过滤指定的是行而不是分组。事实上,WHERE 没有分组的概念。

那么,不使用 WHERE 使用什么呢?SQL 为此提供了另一个子句,就是HAVING 子句。HAVING 非常类似于 WHERE。事实上,目前为止所学过的所有类型的 WHERE 子句都可以用 HAVING 来替代。唯一的差别是,WHERE 过滤行,而 HAVING 过滤分组。

select age,count(1) as number from person group by age having number>1

在这里插入图片描述

说明:HAVING 和 WHERE 的差别
这里有另一种理解方法,WHERE 在数据分组前进行过滤,HAVING 在数据分组后进行过滤。这是一个重要的区别,WHERE 排除的行不包括在分组中。这可能会改变计算值,从而影响 HAVING 子句中基于这些值过滤掉的分组。

分组和排序

GROUP BY 和 ORDER BY 经常完成相同的工作,但它们非常不同,理解这一点很重要

   ORDER BY	                                            GROUP BY
   
对产生的输出排序	                              对行分组,但输出可能不是分组的顺序

任意列都可以使用,甚至非选择的列也可以使用         只可能使用选择列或表达式列,而且必须使用每个选择列表达式

      不一定需要	                           如果与聚集函数一起使用列(或表达式),则必须使用

我们经常发现,用 GROUP BY 分组的数据确实是以分组顺序输出的。但并不总是这样,这不是 SQL 规范所要求的。此外,即使特定的 DBMS 总是按给出的 GROUP BY 子句排序数据,用户也可能会要求以不同的顺序排序。就因为你以某种方式分组数据(获得特定的分组聚集值),并不表示你需要以相同的方式排序输出。应该提供明确的 ORDER BY 子句,即使其效果等同于 GROUP BY 子句。

案例:查询年龄对应人数,按人数倒序输出

select age,count(1) as number from person
group by age
order by number desc

在这里插入图片描述

6、外连接

外连接:以某张表为主,取出里面的所有记录,然后每条与另外一张表进行连接,不管能不能匹配上条件,最终都会保留;能匹配正确保留,不能匹配,其他表的字段都置NULL

外连接将查询多个表中相关联的行,外连接分为:左外连接 和 右外连接

在这里插入图片描述

SELECT 列名1,列名2...,列名n
FROM 表名1   #这是左表
LEFT  [ OUTER ] JOIN 表名2 ON  外连接条件

案例:查询每个人喜欢吃的食物
在这里插入图片描述在这里插入图片描述

select name,like_food from person left join food on person.id = food.person_id

在这里插入图片描述

如果去除like_food为null的行,我们可以使用内连接

7、内连接

根据连接条件从多个表中查询选择数据,显示这些表中与连接条件相匹配的数据行,组合成新记录

SELECT 列名1,列名2,...,列名n
FROM 表名1
[ INNER ] JOIN 表名2 ON 内连接条件

在这里插入图片描述

select name,like_food from person inner join food on person.id = food.person_id

在这里插入图片描述

8、组合查询

可用 UNION 操作符来组合数条 SQL 查询。利用 UNION,可给出多条SELECT 语句,将它们的结果组合成一个结果集。

UNION规则

UNION 必须由两条或两条以上的 SELECT 语句组成,语句之间用关键字UNION 分隔(因此,如果组合四条SELECT 语句,将要使用三个UNION 关键字)

UNION 中的每个查询必须包含相同的列、表达式或聚集函数(不过, 各个列不需要以相同的次序列出)

列数据类型必须兼容:类型不必完全相同,但必须是 DBMS 可以隐含转换的类型(例如,不同的数值类型或不同的日期类型

UNION 从查询结果集中自动去除了重复的行;换句话说,它的行为与一条 SELECT 语句中使用多个 WHERE 子句条件一样。因为

Indiana 州有一个Fun4All 单位,所以两条 SELECT 语句都返回该行。使用 UNION 时,重复的行会被自动取消。

这是 UNION 的默认行为,如果愿意也可以改变它。事实上,如果想返回所有的匹配行,可使用 UNION ALL 而不是 UNION

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐