mysql-day02笔记

1、把查询结果去除重复记录

去重需要使用一个关键字:distinct

	select distinct (字段名) from (表名);

注意:

原表数据不会被修改,只是查询结果去重。
distinct只能出现在所有字段的最前方。

distinct出现在两个字段之前,则表示两个字段联合起来去重。

	select distinct (字段1),(字段2) from (表名);

2、连接查询

2.1、什么是连接查询?

从一张表中单独查询,称为单表查询。
表1和表2联合起来查询数据,从表1中取员工名字,从表2中取部门名字。
这种跨表查询,多张表联合起来查询数据,被称为连接查询。

2.2、连接查询的分类

根据语法的年代分类:

SQL92:1992年的时候出现的语法
SQL99:1999年的时候出现的语法

现在用的多数都是SQL99语法

根据表连接的方式分类:

内连接:
等值连接
非等值连接
自连接

外连接:
左外连接(左连接)
右外连接(右连接)

全连接

2.3、笛卡尔积现象

当两张表进行连接查询时,没有任何条件的限制,如下:

	select (字段1),(字段2) from (表1),(表2);

以上查询语句会导致出现"笛卡尔积现象"

当两张表进行连接查询,没有任何条件限制的时候,最终查询结果条数,是
两张表条数的乘积,这种现象被称为:笛卡尔积现象。(笛卡尔发现的,这是
一个数学现象。)

2.4、避免笛卡尔积现象

连接时加条件,满足这个条件的记录被筛选出来!

select 表1.(字段1),表2.(字段2)
from (表1),(表2)
where 表1.(部门表) = 表2.(部门表);

以上的连接条件是 表1 跟 表2 的部门相同,获取两表同一部门的字段数据,可以避免出现笛卡尔积现象

最终查询的结果条数是正确的条数,但是匹配的过程中,匹配的次数并没有减少,还是跟没有条件
的比较的次数一样,只不过进行了四选一进行了筛选。匹配次数并没有减少。

注意:

通过笛卡尔积现象得出,表的连接次数越多效率越低,尽量避免表的
连接次数。

2.5、内连接之等值连接

例:查询某公司的员工名称与部门名称

SQL92语法:

	select 
		e.(员工名称),d.(部门名称)
	from 
		(员工所在部门表) e,(部门表) d
	where 
		e.(员工部门) = d.(部门); // 条件是等量关系,所以被称为等值连接。

注意:取别名很重要,增加效率
sql92的缺点:

结构不清晰,表的连接条件,和后期进一步筛选的条件,都放到了where后面。

SQL99语法:

	select 
		e.(员工名称),d.(部门名称)
	from
		(员工所在部门表) e
	inner join
		(部门表) d
	on
		e.(员工部门) = d.(部门表); // 条件是等量关系,所以被称为等值连接。

inner关键字可以省略(带着inner可读性会更好,一眼就能看出来是内连接)
sql99优点:

表连接的条件是独立的,连接之后,如果还需要进一步筛选,再往后继续添加where

SQL99语法:

	select 
	...
	from
	a
	join
	b
	on
	a和b的连接条件
	where
	筛选条件

2.6、内连接之非等值连接

例:找出每个员工的薪资等级,要求显示员工名、薪资、薪资等级?

	select 
		e.(工名),e.(薪资),s.(薪资等级)
	from 
		(员工表) e
	inner join 
		(薪资等级表) s
	on 
		e.(员工薪资) between s.(最低薪资) and s.(最高薪资);
		// 条件不是一个等量关系,称为非等值连接。

2.7、内连接之自连接

例:查询员工的上级领导,要求显示员工名和对应的领导名?
自连接:

把一张表看作两张表来查询

员工表李包含了 领导的员工编号 与 每个员工的 上级领导编号
把一张员工表看作两张表,使用别名区分
第一张:(员工表) a 员工
第二章:(员工表) b 领导表

	select
		a.(名称) as '员工名',b.(名称) as '领导名';
	from 
		(员工表) a
	inner join 
		(员工表) b
	on 
		a.(员工领导编号) = b.(领导的员工编号);

重点技巧:

一张表看做两张表。

2.8、外连接

外连接(右外连接):

	select
		e.(名称),d.(名称)
	from 
		(员工表) e
	right outer join  // outer 是可以省略的,带着可读性强。
		(部门表) d
	on 
		e.(员工表部门) = d.(部门表部门);

right代表什么:

表示将join关键字右边的这张表看成主表,主要是为了将
这张表的数据全部查询出来,捎带着关联查询左边的表。
在外连接当中,两张表连接,产生了主次关系。

外连接(左外连接):

	select
		e.(名称),d.(名称)
	from 
		(员工表) e
	left outer join  // outer 是可以省略的,带着可读性强。
		(部门表) d
	on 
		e.(员工表部门) = d.(部门表部门);

总结:

带有right的是右外连接,又叫做右连接。
带有left的是左外连接,又叫做左连接。
任何一个右连接都有左连接的写法。
任何一个左连接都有右连接的写法。

2.9、三,四张表连接

语法:

		select 
			...
		from
			a
		join
			b
		on
			a和b的连接条件
		join
			c
		on
			a和c的连接条件
		right join
			d
		on
			a和d的连接条件

一条SQL中内连接和外连接可以混合。都可以出现!

3、子查询

3.1、什么是子查询

select语句中嵌套select语句,被嵌套的select语句称为子查询。

3.2、子查询都可以出现在哪里

	select
		..(select).
	from
		..(select).
	where
		..(select).

可以出现在 select 后面
可以出现在 from 后面
可以出现在 where 后面

3.3、where 子句中的子查询

例:找出比最低工资高的员工姓名和工资?以下错误案例:

		select 
			(姓名),(工资)
		from
			(员工表) 
		where
			(工资) > min(工资);

以上是错误的,因为在 where 子句中不能直接使用分组函数,可以使用子查询

先分析题目:
	第一步:查询最低工资是多少
	select min(工资) from (表);
	第二步:找出>最低工资的
	select (姓名),(工资) from (员工表) where (工资) > (第一步的结果)//最低工资
	第三步:合并
	select 
		(姓名),(工资) 
	from 
		(员工表) 
		where 
			(工资) > (select min(工资) from (员工表)); // > 最低工资

3.4、from 子句中的子查询

注意:

from后面的子查询,可以将子查询的查询结果当做一张临时表。(技巧)

例:找出每个岗位的平均工资的薪资等级。

	第一步:找出每个岗位的平均工资(按照岗位分组求平均值)
	select 
		(岗位),avg((工资)) 
	from 
		(员工表) 
	group by 
		(岗位); //按照岗位分组
		
	第二步:把以上的查询结果就当做一张真实存在的表t。
	```SQL
		select * from salgrade;//工资等级 s表
第三步:t表和s表进行表连接,
条件:t表avg(工资) between s.(最低工资) and s.(最高工资);

select
	t.*,s.(等级)
from 
	(select (岗位),avg(工资) as avgsal from (员工表) group by (岗位)) t	// 别名 t
join 
	(工资等级表) s
on 
	t.avgasl between s.(最低工资) and s.(最高工资);

#### 3.5、select 后面出现的子查询(了解)
例:找出每个员工员工名称,部门编号,部门名称
```SQL
	select 
		e.(员工姓名),e.(部门编号),
		(select d.(部门名称) from (部门表) d 
		where e.部门编号 = d.(部门编号)) as dname
	from 
		(员工表) e;

以上 select 出现子查询查出了 部门名称
以下错误案例:

	select 
		e.(员工姓名),e.(部门编号),
		(select (部门名称) from (部门表)) as dname
	from 
		(员工表) e;

注意:

对于select后面的子查询来说,这个子查询只能一次返回1条结果,
多于1条,就会报错

4,union 合并查询结果集

例:查询工作岗位是MANAGER和SALESMAN的员工
平常写法:

	select 
		(姓名),(岗位) 
	from 
		(员工表) 
	where 
		(岗位) = 'MANAGER' or (岗位) = 'SALESMAN';
	//或者
	select 
		(姓名),(岗位) 
	from 
		(员工表)  
	where 
		(岗位) in('MANAGER','SALESMAN');

使用 union 合并查询

	select (姓名),(岗位) from (员工表) where (岗位) = 'MANAGER'
    union
    select (姓名),(岗位) from (员工表) where (岗位) = 'SALESMAN';

相比较:

union的效率要高一些。对于表连接来说,每连接一次新 表,
则匹配的次数满足笛卡尔积,成倍的翻。。。
但是union可以减少匹配的次数。在减少匹配次数的情况下,
还可以完成两个结果集的拼接。

	匹配次数:
          a 连接 b 连接 c
          a 10条记录
          b 10条记录
          c 10条记录
          匹配次数是:1000

          a 连接 b一个结果:10 * 10 --> 100次
          a 连接 c一个结果:10 * 10 --> 100次
          使用union的话是:100次 + 100次 = 200次。
          (union把乘法变成了加法运算)

union注意事项:
1、union在进行结果集合并的时候,要求两个结果集的列数相同。以下错误案例:

	select (姓名),(岗位) from (员工表) where (岗位) = 'MANAGER'
    union
    select (姓名) from (员工表) where (岗位) = 'SALESMAN';

2、结果集合并时列和列的数据类型也要一致。

在MySQL里面可以,oracle 语法比较严格,不可以

5、limit(重要)

5.1、limit作用

作用:

将查询结果集的一部分取出来。通常使用在分页查询当中。
例如:
百度默认:一页显示10条记录。

分页的作用:

为了提高用户的体验,因为一次全部都查出来,用户体验差。
分页可以一页一页翻页看。(类似百度的页数)

5.2、limit的用法

完整用法:

	limit startIndex, length
	//startIndex是起始下标,length是长度。
	//起始下标从0开始。

缺省用法:

	limit 5; //取出前5个值

例:按照薪资降序,取出排名在前5名的员工

	select
		(姓名),(工资)
	from 
		(员工表)
	order by	//工资排序
		(工资) desc
	limit 5;	//取出前5个

以下的结果相同:

	select
		(姓名),(工资)
	from 
		(员工表)
	order by	//工资排序
		(工资) desc
	limit 0,5;	//取出0到5个

5.3、注意:mysql当中limit在order by之后执行

5.4、取出工资排名在[3-5]名的员工

	select
		(姓名),(工资)
	from 
		(员工表)
	order by	//工资排序
		(工资) desc
	limit 
		2,3;	//取出3到5个

注意:

2表示起始位置从下标2开始,就是第三条记录。
3表示长度。

5.5、分页

每页显示3条记录:

第1页:limit 0,3 [0 1 2]
第2页:limit 3,3 [3 4 5]
第3页:limit 6,3 [6 7 8]
第4页:limit 9,3 [9 10 11]

记分页的公式:

	limit ((第几页)-1) * (每页显示的条数) , (每页显示的条数)

6、关于DQL语句的大总结:

    select 
		...
	from
		...
	where
		...
	group by
		...
	having
		...
	order by
		...
	limit
		...

执行顺序:

1、from
2、where
3、group by
4、having
5、select
6、order by
7、limit…

7、表的创建(建表)

7.1、建表的语法格式:(建表属于DDL语句,DDL包括:create drop alter)

语法:

create table ((表名))((字段名1) 数据类型,(字段名2) 数据类型,(字段名3) 数据类型)

可以这样写:

create table 表名(
		字段名1 数据类型, 
		字段名2 数据类型, 
		字段名3 数据类型
	);

命名方式:

表名:建议以t_ 或者 tbl_开始,可读性强。见名知意。
字段名:见名知意。
表名和字段名都属于标识符。

7.2、mysql中的数据类型

常见的数据类型:

1、varchar(最长255)
2、char(最长255)
3、int(最长11)
4、bigint
5、float
6、double
7、date
8、datetime
9、clob
10、blob

说明:
varchar(最长255):

可变长度的字符串
比较智能,节省空间。
会根据实际的数据长度动态分配空间。

优点:节省空间
缺点:需要动态分配空间,速度慢。

char(最长255):

定长字符串
不管实际的数据长度是多少。
分配固定长度的空间去存储数据。
使用不恰当的时候,可能会导致空间的浪费。

优点:不需要动态分配空间,速度快。
缺点:使用不当可能会导致空间的浪费。

varchar和char怎么选择:

假如储存性别使用char,因为性别是固定长度的字符串,所以选择char。
假如储存姓名使用varchar,每一个人的名字长度不同,所以选择varchar。

int(最长11):

数字中的整数型。等同于java的int。

bigint:

数字中的长整型。等同于java中的long。

float:

单精度浮点型数据

double:

双精度浮点型数据

date:

短日期类型

datetime:

长日期类型

clob:

字符大对象
最多可以存储4G的字符串。
比如:存储一篇文章,存储一个说明。
超过255个字符的都要采用CLOB字符大对象来存储。
Character Large OBject:CLOB

blob:

二进制大对象
Binary Large OBject
专门用来存储图片、声音、视频等流媒体数据。
往BLOB类型的字段上插入数据的时候,例如插入一个图片、视频等,
你需要使用IO流才行。

7.3、创建一个学生表

学生表有字段:学号、姓名、年龄、性别、邮箱地址

create table t_student(
	no int,
    name varchar(32),
    sex char(1),
    age int(3),
    email varchar(255)
);

7.4、删除表

删除 t_student 表

drop table t_student; // 当这张表不存在的时候会报错!
// 如果这张表存在的话,删除
drop table if exists t_student;

7.5、插入数据 insert (DML)

语法格式:

insert into 表名(字段名1,字段名2,字段名3…) values(值1,值2,值3);

注意:

字段名和值要一一对应,数量要对应。数据类型要对应。

insert语句但凡是执行成功了,那么必然会多一条记录。
没有给其它字段指定值的话,默认值是NULL。

insert语句中的“字段名”可以省略

	insert into t_student values(2,'zhangsan','f',20,'[email protected]');

注意:

前面的字段名省略的话,等于都写上了!所以值也要全部写上

7.5、插入日期

数字格式化:format(数字,‘格式’)

select (姓名),format((工资),'$999.999') from (表名); //结果保留三位小数

str_to_date(‘字符串日期’, ‘日期格式’):将字符串varchar类型转换成date类型
date_format(日期类型数据, ‘日期格式’):将date类型转换成具有一定格式的>varchar>字符串类型。

数据库命名规范:所有的标识符都是全部小写,单词和单词之间使用下划线进行衔接。

mysql的日期格式:

%Y 年
%m 月
%d 日
%h 时
%i 分
%s 秒

str_to_date:

函数可以把字符串varchar转换成日期date类型数据,
通常使用在插入insert方面,因为插入的时候需要一个日期类型的数据,
需要通过该函数将字符串转换成date。

如果提供的日期字符串是这个格式,str_to_date函数就不需要了

%Y-%m-%d

date_format:

date_format 函数可以将日期类型转换成特定格式的字符串。

注意:

mysql默认的日期格式:’%Y-%m-%d’

7.6、date 和 datetime 两个类型的区别

区别:

date是短日期:只包括年月日信息。
datetime是长日期:包括年月日时分秒信息。

默认格式:

mysql短日期默认格式:%Y-%m-%d
mysql长日期默认格式:%Y-%m-%d %h:%i:%s

获取当前时间:

在mysql中获取系统当前时间可以使用 now() 函数,获取的时间带有:时分秒信息,是>datetime类型的。

	insert into 
		t_user(id,name,birth,create_time) 
	values 
		(2,'zhangsan','1991-10-01',now())//now()当前系统时间

7.7、修改update(DML)

语法:

update 表名 set 字段名1=值1,字段名2=值2,字段名3=值3… where 条件;

注意:

没有条件限制会导致所有数据全部更新。
带条件的话修改的就是与条件相符合的字段
= 号右边的值更新左边的字段

7.8、删除数据 delete (DML)

语法:

delete from 表名 where 条件;

注意:

没有条件,整张表的数据会全部删除!
带条件的话删除的就是与条件相符合的记录
mysql默认的日期格式:’%Y-%m-%d’


整理写了很久的笔记,如有错误还请大佬指出。
嘿嘿,三连不过分吧!

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
)">
< <上一篇

)">
下一篇>>