您的位置:首页 > 数据库 > MySQL

MySQL传智播客--Lession13-Lession24笔记

2016-07-07 16:35 281 查看
================lession13==列属性=============================

是否为空

规定一个字段的值,是否可以是null

Null | not null

create table php1(

a int not null,

b int

);

insert into php1 (a) values(10);

mysql> select * from php1;

+----+------+

| a  | b    |

+----+------+

| 10 | NULL | 

+----+------+

insert into php1 (b) values(11);//数据库崩溃了

默认值属性:

Default value 来声明

默认值,在没有为该字段设置值时启用。而且默认值的设置,需要使用固定值

常见的是:一个字段不能为空,而且存在默认值。

create table php2(

a int not null default 10,

b int not null default 21

);

insert into php2 (a) values(10);

insert into php2 (b) values(11);

create table php3(

a int not null default 10,

b int  default 21

);

insert into php3 values(20,null);

主键:PK,primary key.

可以唯一标识,某条记录的字段或者是字段的集合,就是主键。

主键可以是真实实体的属性。

但是常用的好的解决方案是:

利用一个与实体信息不相关的属性,作为唯一标识

主键与业务逻辑不发生关系,只用来标识记录。

设置主键的语法:

Primary key完成。

两种方案:

1.字段上设置

方案一:

create table teacher(

t_id int primary key,

t_name varchar(5),

classs_name varchar(6),

days tinyint unsigned

);

insert into teacher values(1,'韩A','0331',25);

insert into teacher values(1,'李A','0228',22); // 主键不能相同

insert into teacher values(null,'李A','0228',22); // 主键也不能为空

insert into teacher values(-1,'李A','0228',22); // 主键能否为负数看数据类型

方案二:(可以设置多列作为主键)

create table teacher2(

t_id int,

t_name varchar(5),

classs_name varchar(6),

days tinyint unsigned,

primary key(t_id)

);

create table teacher3(

t_id int,

t_name varchar(5),

class_name varchar(6),

days tinyint unsigned,

primary key(t_name,class_name)

);

create table teacher4(

t_name varchar(5),

class_name varchar(6),

days tinyint unsigned,

primary key(t_name,class_name) //一个主键包含2个字段

);

注意:组合主键的意义

一个主键内包括多个字段,而不是多个字段都是主键。

只需要一个唯一标识即可,mysql规定只能存在一个主键。

要求:

常见的设计,每一个表都应该存在一个可以唯一标识的主键字段。最好与实体没有联系,

不是实体属性字段。

=======================lession14==自动增长=============================

自动增长:

为每条记录提供给一个唯一的标识。

每次插入记录时,将某个字段的值自动增加1;

使用auto increment 标识。

需要整型,还需要有索引。

create table teacher5(

t_id int primary key auto_increment,

t_name varchar(5),

classs_name varchar(6),

days tinyint unsigned

);

插入数据时,可以选择插入null,或者不插入:

insert into teacher5 values(null,'韩B','0228',34);

+------+--------+-------------+------+

| t_id | t_name | classs_name | days |

+------+--------+-------------+------+

|    1 | 韩B   | 0228        |   34 | 

+------+--------+-------------+------+

insert into teacher5 (t_name, classs_name, days)values('韩B','0228',34);

+------+--------+-------------+------+

| t_id | t_name | classs_name | days |

+------+--------+-------------+------+

|    1 | 韩B   | 0228        |   34 | 

|    2 | 韩B   | 0228        |   34 | 

+------+--------+-------------+------+

自动增长的初始值,是可以设置的,默认是1

通过表选项;auto_increment=n

alter table teacher5 auto_increment 10;

insert into teacher5 values(null,'韩B','0115',32);

+------+--------+-------------+------+

| t_id | t_name | classs_name | days |

+------+--------+-------------+------+

|    1 | 韩B   | 0228        |   34 | 

|    2 | 韩B   | 0228        |   34 | 

|   10 | 韩B   | 0115        |   32 | 

+------+--------+-------------+------+

如果n的值小于已经存在的主键的值

alter table teacher5 auto_increment 5;

insert into teacher5 values(null,'赵A','0115',32);

+------+--------+-------------+------+

| t_id | t_name | classs_name | days |

+------+--------+-------------+------+

|    1 | 韩B   | 0228        |   34 | 

|    2 | 韩B   | 0228        |   34 | 

|   10 | 韩B   | 0115        |   32 | 

|   11 | 赵A   | 0115        |   32 | 

+------+--------+-------------+------+

insert into teacher5 values(5,'谢A','0115',32);

是否可以手动插入该列的值?可以

+------+--------+-------------+------+

| t_id | t_name | classs_name | days |

+------+--------+-------------+------+

|    1 | 韩B   | 0228        |   34 | 

|    2 | 韩B   | 0228        |   34 | 

|   10 | 韩B   | 0115        |   32 | 

|   11 | 赵A   | 0115        |   32 | 

|    5 | 谢A   | 0115        |   32 | 

+------+--------+-------------+------+

该列是否可以更新?可以

update teacher5 set t_id=21 where t_name='赵A';

+------+--------+-------------+------+

| t_id | t_name | classs_name | days |

+------+--------+-------------+------+

|    1 | 韩B   | 0228        |   34 | 

|    2 | 韩B   | 0228        |   34 | 

|   10 | 韩B   | 0115        |   32 | 

|   21 | 赵A   | 0115        |   32 | 

|    5 | 谢A   | 0115        |   32 | 

+------+--------+-------------+------+

测试:自动增长设置为20,数据库内已经存在大于二十的记录,删除所有的大于20的记录。

问:插入数据时,ID为多少? 为22,数据库会保留原来已经存在的记录ID

create table teacher6(

t_id int primary key auto_increment,

t_name varchar(5),

class_name varchar(6),

days tinyint unsigned

);

insert into teacher6 values(21,'谢A','0115',32);

mysql> select * from teacher6;

+------+--------+------------+------+

| t_id | t_name | class_name | days |

+------+--------+------------+------+

|   21 | 谢A   | 0115       |   32 | 

+------+--------+------------+------+

alter table teacher6 auto_increment 20;

ql> delete from teacher6 where t_id=21;

Query OK, 1 row affected (0.12 sec)

insert into teacher6 values(null,'李A','0116',30);

mysql> select * from teacher6;

+------+--------+------------+------+

| t_id | t_name | class_name | days |

+------+--------+------------+------+

|   22 | 李A   | 0116       |   30 | 

+------+--------+------------+------+

=======================lession15==实体(1)=============================

实体:(1)常用信息表(2)详细信息表(一对一的关系)

1:1 

设计:

两个实体表内,存在相同的主键字段。

如果记录的主键值等于另一个关系表内记录的主键值,则两条记录对应 1:1对应。

1:N (一对多)

一个实体,对应多个其他 实体。

例如一个班级对应多个学生。

设计:

在多的那端(N那端),增加一个字段,用于指向该实体所属的另外的实体标识。

M:N多对多:

例如一个老师教过很多班级。一个班级也同时被多个老师教过。

设计:

典型的,利用一个中间表,表示实体之间的对应关系。

讲师主键 讲师姓名

1 韩顺平

3 韩忠康

班级主键 班级号
开班时间

29 PHP0228
2013-02-28

30 PHP0331
2013-03-31

讲师ID 班级ID

1 29

3 29

3 30

中间表的每个记录,表示一个关系。

可以分析:

一个M:N

1:M

1:N

来实现。

作业:用Microsoft Visio画出上面的关系图

=======================lession16==实体(2)=============================

练习更多的实体直接的关系,以及模型

=======================lession17=外键(1)=============================

外键 foreign key

概念:

如果一个实体的(student)的某个字段(student: class id), 指向(引用)另一个实体(class)的

主键(class:class_id),就称student实体的class_id是外键。

被指向的实体称为主实体(主表),也叫父实体(父表)。 class

负责指向的实体,称之为从实体(从表),也叫子实体(子表)。 Student

作用:

用于约束处于关系内的实体。

增加子表记录时,是否有与之对应的父表记录。

在删除或者更新主表记录时,从表应该如何处理相关的记录。

定义一个外键:

在从表上,增加一个字段,指向主表的主键。

使用关键字foreign key

// comment 这个是注释的意思

drop table if exists itcast_class; // 如果已经存在表itcast_class则删除

create table itcast_class(

class_id int primary key auto_increment,

class_name varchar(10) not null default 'itcast_php' comment '班级名称'

)ENGINE=InnoDB character set utf8;

drop table if exists itcast_student;

create table itcast_student(

stu_id int primary key auto_increment,

stu_name varchar(10) not null default '',

class_id int,

foreign key(class_id) references itcast_class (class_id)

)ENGINE=InnoDB character set utf8;

//奇怪的是设计了外键它还可以插入

Insert into itcast_student valuse(null,'lishi',1);

=======================lession18=外键(1)=============================

设置级联操作:

在主表数据发生改变时,与之关联的从表数据应该如何处理:

主表更新:

主表删除:

使用关键字:

On update

On delete来标识。

允许的级联动作:

Cascade关联操作,如果主表被更新或删除,那么从表也会执行相应的操作。

Set null 设置为null,表示从表不指向任何 主表记录。

Restrict: 拒绝主表的相关操作。

修改这个外键:

先删除,再新建。通过修改表完成。

Alter table tbl_name drop foreign key (class_id);

删除外键需要通过指定外键名称达到目的:

可以通过在创建外键是,指定名称,或者使用mysql默认生成的名称

Set null操作:

关联子设置为空:

测试删除:

Alter table tbl_name add foreign key (class_id);

// DROP FOREIGN KEY fk_symbol

 CONSTRAINT `itcast_student_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `itcast_class` (`class_id`)

Alter table itcast_student drop foreign key itcast_student_ibfk_1;

Alter table itcast_student add foreign key (class_id) references itcast_class (class_id) 

on delete set null; // on delete set null意思是删除时,将从表外键,设置为null(前提可以为null)

Delete from itcast_class where class_id=1;

Cascade级联操作:

Insert into itcast_class values(1,'php0331');

Update itcaset_student set class_id=1 where stu_id=1;

Alter table itcast_student add foreign key (class_id) references itcast_class (class_id) 

on delete cascade; // cascade级联操作,删除主表时从表的记录也会被删除一般建议是set null

//因为 cascade是不可逆的

测试删除:

delete from itcast_class where class_id=1;

主表和从表都被删除了

On update

指的是只有主表的主键发生变化,才会对从表发生影响

insert into itcast_class values(1,'php0331');

Update itcast_student set class_id=1 where stu_id=2;

Alter table itcast_student drop foreign key itcast_student_ibfk_1;

Alter table itcast_student add foreign key (class_id) references itcast_class (class_id) 

on delete cascade  //cascade和set null只能在同一时间设置一个

on update restrict;  //更新时不允许操作

Alter table itcast_student drop foreign key itcast_student_ibfk_1;

Alter table itcast_student add foreign key (class_id) references itcast_class (class_id) 

on update restrict;  //更新时不允许操作

Restrict

更新存在关联的主表数据的主键字段:

mysql> update itcast_class set class_id=2 where class_name='php0331';

ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`test1/itcast_student`, CONSTRAINT `itcast_student_ibfk_4` FOREIGN KEY (`class_id`) REFERENCES `itcast_class` (`class_id`))

=======================lession19=存储引擎=============================

默认的服务器表类型,通过my.ini可以配置:

在mysql5.5之后是默认是InnoDB

Default-storage-engine=Myisam,  or   InnoDB

在创建表或者编辑表时,可以指定表的存储引擎。

利用表属性:engine表引擎类型

Engine Myisam

Engine InnoDB

//如果表有外键约束存在则操作不成功

Alter table itcast_class engine Myisam;

Alter table itcast_class engine InnoDB;

Innodb & myisam区别:

保存的文件的方式不同:

Myisam:

一个表,三个文件

Tbl_name.frm 结构

Tbl_name.myd 数据

Tbl_name.myi 索引

Innodb:

一个表一个文件:

Tbl_name.frm 结构

所有的innodb表,都使用相同的

innodb存储表空间来保存数据和索引。

Myisam:

优势:插入,索引 ,

劣势:表锁(整个表都锁起来)所以高并发支持不好

Innodb:

优势:更新,删除,高并发

补充:但是甲骨文在倾向于innodb加跟多功能比如5.5开始innodb支持全文索引

选择存储引擎的依据:

1.性能

2.功能

=======================lession20 order by=============================

Order by 

按字段值进行排序

Order by 字段 升序或降序(asc|desc)  //校对规则决定排序关系

// asc (ascending)  desc (descending)

允许多字段排序,

指的是,先按照第一个字段排序,如果说,不能区分,才使用第二个字段。以此类推

Create table teacher_class (

Id int primary key auto_increment,

T_name varchar(4),

Gender enum('female','male'),

C_name varchar(6),

Room int unsigned,

Days tinyint,

Begin_date date,

End_date date

);

Iinsert into teacher_class values(1,'韩信','male','php0115',207,21,'2013-01-15','2013-02-20');

insert into teacher_class values(null,'韩信','male','php0228',106,18,'2013-02-28','2013-03-30');

insert into teacher_class values(null,'韩信','male','php0331',102,22,'2013-03-31','2013-05-05');

insert into teacher_class values(null,'李白','male','php0115',207,20,'2013-02-22','2013-03-25');

insert into teacher_class values(null,'李白','male','php0228',204,22,'2013-03-31','2013-04-29');

insert into teacher_class values(null,'韩非子','male','php0115',207,15,'2013-03-27','2013-04-18');

insert into teacher_class values(null,'韩非子','male','php0331',106,15,'2013-5-28','2013-06-15');

mysql> select * from teacher_class;

+----+--------+--------+--------+------+------+------------+------------+

| id | t_name | gender | c_name | room | days | begin_date | end_date   |

+----+--------+--------+--------+------+------+------------+------------+

|  1 | 韩�   | male   | php011 |  207 |   21 | 2013-01-15 | 2013-02-20 | 

|  2 | 韩�   | male   | php022 |  106 |   18 | 2013-02-28 | 2013-03-30 | 

|  3 | 韩�   | male   | php033 |  102 |   22 | 2013-03-31 | 2013-05-05 | 

|  5 | 李�   | male   | php011 |  207 |   20 | 2013-02-22 | 2013-03-25 | 

|  6 | 李�   | male   | php022 |  204 |   22 | 2013-03-31 | 2013-04-29 | 

|  7 | 韩�   | male   | php011 |  207 |   15 | 2013-03-27 | 2013-04-18 | 

|  8 | 韩�   | male   | php033 |  106 |   15 | 2013-05-28 | 2013-06-15 | 

+----+--------+--------+--------+------+------+------------+------------+

mysql> select * from teacher_class order by days desc;

+----+--------+--------+--------+------+------+------------+------------+

| id | t_name | gender | c_name | room | days | begin_date | end_date   |

+----+--------+--------+--------+------+------+------------+------------+

|  3 | 韩�   | male   | php033 |  102 |   22 | 2013-03-31 | 2013-05-05 | 

|  6 | 李�   | male   | php022 |  204 |   22 | 2013-03-31 | 2013-04-29 | 

|  1 | 韩�   | male   | php011 |  207 |   21 | 2013-01-15 | 2013-02-20 | 

|  5 | 李�   | male   | php011 |  207 |   20 | 2013-02-22 | 2013-03-25 | 

|  2 | 韩�   | male   | php022 |  106 |   18 | 2013-02-28 | 2013-03-30 | 

|  7 | 韩�   | male   | php011 |  207 |   15 | 2013-03-27 | 2013-04-18 | 

|  8 | 韩�   | male   | php033 |  106 |   15 | 2013-05-28 | 2013-06-15 | 

+----+--------+--------+--------+------+------+------------+------------+

mysql> select * from teacher_class order by days asc;

+----+--------+--------+--------+------+------+------------+------------+

| id | t_name | gender | c_name | room | days | begin_date | end_date   |

+----+--------+--------+--------+------+------+------------+------------+

|  7 | 韩�   | male   | php011 |  207 |   15 | 2013-03-27 | 2013-04-18 | 

|  8 | 韩�   | male   | php033 |  106 |   15 | 2013-05-28 | 2013-06-15 | 

|  2 | 韩�   | male   | php022 |  106 |   18 | 2013-02-28 | 2013-03-30 | 

|  5 | 李�   | male   | php011 |  207 |   20 | 2013-02-22 | 2013-03-25 | 

|  1 | 韩�   | male   | php011 |  207 |   21 | 2013-01-15 | 2013-02-20 | 

|  3 | 韩�   | male   | php033 |  102 |   22 | 2013-03-31 | 2013-05-05 | 

|  6 | 李�   | male   | php022 |  204 |   22 | 2013-03-31 | 2013-04-29 | 

+----+--------+--------+--------+------+------+------------+------------+

mysql> select * from teacher_class order by days desc,begin_date;

+----+--------+--------+--------+------+------+------------+------------+

| id | t_name | gender | c_name | room | days | begin_date | end_date   |

+----+--------+--------+--------+------+------+------------+------------+

|  3 | 韩�   | male   | php033 |  102 |   22 | 2013-03-31 | 2013-05-05 | 

|  6 | 李�   | male   | php022 |  204 |   22 | 2013-03-31 | 2013-04-29 | 

|  1 | 韩�   | male   | php011 |  207 |   21 | 2013-01-15 | 2013-02-20 | 

|  5 | 李�   | male   | php011 |  207 |   20 | 2013-02-22 | 2013-03-25 | 

|  2 | 韩�   | male   | php022 |  106 |   18 | 2013-02-28 | 2013-03-30 | 

|  7 | 韩�   | male   | php011 |  207 |   15 | 2013-03-27 | 2013-04-18 | 

|  8 | 韩�   | male   | php033 |  106 |   15 | 2013-05-28 | 2013-06-15 | 

+----+--------+--------+--------+------+------+------------+------------+

mysql> select * from teacher_class order by days desc,begin_date desc;

+----+--------+--------+--------+------+------+------------+------------+

| id | t_name | gender | c_name | room | days | begin_date | end_date   |

+----+--------+--------+--------+------+------+------------+------------+

|  3 | 韩�   | male   | php033 |  102 |   22 | 2013-03-31 | 2013-05-05 | 

|  6 | 李�   | male   | php022 |  204 |   22 | 2013-03-31 | 2013-04-29 | 

|  1 | 韩�   | male   | php011 |  207 |   21 | 2013-01-15 | 2013-02-20 | 

|  5 | 李�   | male   | php011 |  207 |   20 | 2013-02-22 | 2013-03-25 | 

|  2 | 韩�   | male   | php022 |  106 |   18 | 2013-02-28 | 2013-03-30 | 

|  8 | 韩�   | male   | php033 |  106 |   15 | 2013-05-28 | 2013-06-15 | 

|  7 | 韩�   | male   | php011 |  207 |   15 | 2013-03-27 | 2013-04-18 | 

+----+--------+--------+--------+------+------+------------+------------+

mysql> select * from teacher_class order by days desc,begin_date desc, end_date asc;

+----+--------+--------+--------+------+------+------------+------------+

| id | t_name | gender | c_name | room | days | begin_date | end_date   |

+----+--------+--------+--------+------+------+------------+------------+

|  6 | 李�   | male   | php022 |  204 |   22 | 2013-03-31 | 2013-04-29 | 

|  3 | 韩�   | male   | php033 |  102 |   22 | 2013-03-31 | 2013-05-05 | 

|  1 | 韩�   | male   | php011 |  207 |   21 | 2013-01-15 | 2013-02-20 | 

|  5 | 李�   | male   | php011 |  207 |   20 | 2013-02-22 | 2013-03-25 | 

|  2 | 韩�   | male   | php022 |  106 |   18 | 2013-02-28 | 2013-03-30 | 

|  8 | 韩�   | male   | php033 |  106 |   15 | 2013-05-28 | 2013-06-15 | 

|  7 | 韩�   | male   | php011 |  207 |   15 | 2013-03-27 | 2013-04-18 | 

+----+--------+--------+--------+------+------+------------+------------+

注意:如果是分组,则应该使用对分组字段进行排序的group by语法。

=======================lession21=Limit=============================

Limit:

限制获得的记录的数量:

Row1 0

Row2 1

Row3 2

Row4 3

Row5 4

Limit的语法:

Limit offset ,row count

Offset 偏移量,从0开始。可以省略

默认为0。

Row_count 总记录数,如果数量大于,余下的记录数,则获取所有余下的即可:

需要获得 row2-row4

Offset 1

Row_count 3

mysql> select * from teacher_class limit 3,4;

+----+--------+--------+--------+------+------+------------+------------+

| id | t_name | gender | c_name | room | days | begin_date | end_date   |

+----+--------+--------+--------+------+------+------------+------------+

|  5 | 李�   | male   | php011 |  207 |   20 | 2013-02-22 | 2013-03-25 | 

|  6 | 李�   | male   | php022 |  204 |   22 | 2013-03-31 | 2013-04-29 | 

|  7 | 韩�   | male   | php011 |  207 |   15 | 2013-03-27 | 2013-04-18 | 

|  8 | 韩�   | male   | php033 |  106 |   15 | 2013-05-28 | 2013-06-15 | 

+----+--------+--------+--------+------+------+------------+------------+

注意:设置了一个表的id primary key auto_increment ;后当删除一个记录假设这记录的ID为

4且id=4为当时表ID最大的值,那么再插入一条记录后,id是从5开始的。

Offset 偏移量,从0开始。可以省略,默认为0

mysql> select * from teacher_class limit 5;

+----+--------+--------+--------+------+------+------------+------------+

| id | t_name | gender | c_name | room | days | begin_date | end_date   |

+----+--------+--------+--------+------+------+------------+------------+

|  1 | 韩�   | male   | php011 |  207 |   21 | 2013-01-15 | 2013-02-20 | 

|  2 | 韩�   | male   | php022 |  106 |   18 | 2013-02-28 | 2013-03-30 | 

|  3 | 韩�   | male   | php033 |  102 |   22 | 2013-03-31 | 2013-05-05 | 

|  5 | 李�   | male   | php011 |  207 |   20 | 2013-02-22 | 2013-03-25 | 

|  6 | 李�   | male   | php022 |  204 |   22 | 2013-03-31 | 2013-04-29 | 

+----+--------+--------+--------+------+------+------------+------------+

Row_count 总记录数,如果数量大于,余下的记录数,则获取所有余下的即可:

mysql> select * from teacher_class limit 5,100;

+----+--------+--------+--------+------+------+------------+------------+

| id | t_name | gender | c_name | room | days | begin_date | end_date   |

+----+--------+--------+--------+------+------+------------+------------+

|  7 | 韩�   | male   | php011 |  207 |   15 | 2013-03-27 | 2013-04-18 | 

|  8 | 韩�   | male   | php033 |  106 |   15 | 2013-05-28 | 2013-06-15 | 

+----+--------+--------+--------+------+------+------------+------------+

=======================lession22=distinct=============================

Distinct

去除重复记录:

重复的记录,指的是,字段值,都相同的记录,而不是部分字段相同的记录。

相对的是all,表示所有。默认就是all行为。

mysql> select days from teacher_class;

+------+

| days |

+------+

|   21 | 

|   18 | 

|   22 | 

|   20 | 

|   22 | 

|   15 | 

|   15 | 

+------+

7 rows in set (0.00 sec)

mysql> select distinct days from teacher_class;

+------+

| days |

+------+

|   21 | 

|   18 | 

|   22 | 

|   20 | 

|   15 | 

+------+

5 rows in set (0.09 sec)

mysql> select * from teacher_class;

+----+--------+--------+--------+------+------+------------+------------+

| id | t_name | gender | c_name | room | days | begin_date | end_date   |

+----+--------+--------+--------+------+------+------------+------------+

|  1 | 韩�   | male   | php011 |  207 |   21 | 2013-01-15 | 2013-02-20 | 

|  2 | 韩�   | male   | php022 |  106 |   18 | 2013-02-28 | 2013-03-30 | 

|  3 | 韩�   | male   | php033 |  102 |   22 | 2013-03-31 | 2013-05-05 | 

|  5 | 李�   | male   | php011 |  207 |   20 | 2013-02-22 | 2013-03-25 | 

|  6 | 李�   | male   | php022 |  204 |   22 | 2013-03-31 | 2013-04-29 | 

|  7 | 韩�   | male   | php011 |  207 |   15 | 2013-03-27 | 2013-04-18 | 

|  8 | 韩�   | male   | php033 |  106 |   15 | 2013-05-28 | 2013-06-15 | 

+----+--------+--------+--------+------+------+------------+------------+

7 rows in set (0.00 sec)

mysql> select distinct * from teacher_class;

+----+--------+--------+--------+------+------+------------+------------+

| id | t_name | gender | c_name | room | days | begin_date | end_date   |

+----+--------+--------+--------+------+------+------------+------------+

|  1 | 韩�   | male   | php011 |  207 |   21 | 2013-01-15 | 2013-02-20 | 

|  2 | 韩�   | male   | php022 |  106 |   18 | 2013-02-28 | 2013-03-30 | 

|  3 | 韩�   | male   | php033 |  102 |   22 | 2013-03-31 | 2013-05-05 | 

|  5 | 李�   | male   | php011 |  207 |   20 | 2013-02-22 | 2013-03-25 | 

|  6 | 李�   | male   | php022 |  204 |   22 | 2013-03-31 | 2013-04-29 | 

|  7 | 韩�   | male   | php011 |  207 |   15 | 2013-03-27 | 2013-04-18 | 

|  8 | 韩�   | male   | php033 |  106 |   15 | 2013-05-28 | 2013-06-15 | 

+----+--------+--------+--------+------+------+------------+------------+

7 rows in set (0.00 sec)

mysql> select days,begin_date from teacher_class;

+------+------------+

| days | begin_date |

+------+------------+

|   21 | 2013-01-15 | 

|   18 | 2013-02-28 | 

|   22 | 2013-03-31 | 

|   20 | 2013-02-22 | 

|   22 | 2013-03-31 | 

|   15 | 2013-03-27 | 

|   15 | 2013-05-28 | 

+------+------------+

7 rows in set (0.00 sec)

Distinct后面跟两个字段时,要两个字段同时相同才会去掉,如果只是两个字段中的一个字段相同时,会保留下来

mysql> select distinct days,begin_date from teacher_class;

+------+------------+

| days | begin_date |

+------+------------+

|   21 | 2013-01-15 | 

|   18 | 2013-02-28 | 

|   22 | 2013-03-31 | 

|   20 | 2013-02-22 | 

|   15 | 2013-03-27 | 

|   15 | 2013-05-28 | 

+------+------------+

6 rows in set (0.00 sec)

=======================lession23=union(1)=============================

联合查询

mysql> select t_name,days from teacher_class where c_name='php011';

+--------+------+

| t_name | days |

+--------+------+

| 韩�   |   21 | 

| 李�   |   20 | 

| 韩�   |   15 | 

+--------+------+

3 rows in set (0.00 sec)

mysql> select t_name,days from teacher_class where c_name='php011' order by days desc;

+--------+------+

| t_name | days |

+--------+------+

| 韩�   |   21 | 

| 李�   |   20 | 

| 韩�   |   15 | 

+--------+------+

3 rows in set (0.00 sec)

mysql> select t_name,days from teacher_class where c_name='php011' order by days desc limit 1;

+--------+------+

| t_name | days |

+--------+------+

| 韩�   |   21 | 

+--------+------+

mysql> select t_name,days from teacher_class where c_name='php022' order by days desc limit 1;

+--------+------+

| t_name | days |

+--------+------+

| 李�   |   22 | 

+--------+------+

=======================lession24=union(2)=============================

将多条select 语句的结果,合并到一起。称之为联合操作。

union联合

使用union关键字 联合 两个select语句即可:

(select t_name,days from teacher_class where c_name='php011' order by days desc limit 1)

Union

(select t_name,days from teacher_class where c_name='php022' order by days desc limit 1);

mysql> (select t_name,days from teacher_class where c_name='php011' order by days desc limit 1)

    -> Union

    -> (select t_name,days from teacher_class where c_name='php022' order by days desc limit 1);

+--------+------+

| t_name | days |

+--------+------+

| 韩�   |   21 | 

| 李�   |   22 | 

+--------+------+

2 rows in set (0.03 sec)

场景:

获得数据的条件,出现逻辑冲突,或者很难在一个逻辑内表示,就可以拆分成多个逻辑,分别实现最后将结果合并到一起。

Union all环境:

获得0115班所有代课老师,结果按照代课天数升序排序,同时需要获得0228班,结果按照降序排序

注意:如果union的结果存在重复的记录,那么会消除重复。可以通过union选项all达到目的。

(Select t_name,days,c_name from teacher_class where c_name='php0115' order by days limit 10) Union 

(Select t_name,days,c_name from teacher_class where c_name='php0228' order by days desc limit 10);

(Select t_name,days,c_name from teacher_class where c_name='php0115' order by days limit 10) Union all

(Select t_name,days,c_name from teacher_class where c_name='php0228' order by days desc limit 10);

排序:

子语句结果的排序:

1.将子语句包裹子括号内。

2.子语句的order by,只有在order by 配合limit时,才生效。原因是:union在做子语句时,会对没有limit子句的order by 优化(忽略);

对所有结果进行统一排序:

只需要在最后一个select语句后,增加相应的排序规则即可:

(Select t_name,days,c_name from teacher_class where c_name='php0115' order by days limit 10) Union all

(Select t_name,days,c_name from teacher_class where c_name='php0228' order by days desc limit 10) order by days;

提示:

子语句没有括号也可以,但是读起来不友好,建议每一个子语句,加一个括号。

注意:

规定,多个select语句的检索到的字段数,必须一致。

mysql> (Select days,c_name from teacher_class where c_name='php0115' order by days limit 10) Union all (Select t_name,days,c_name from teacher_class where c_name='php0115' order by days limit 10) Union all(Select t_name,days,c_name from teacher_class where
c_name='php0228' order by days desc limit 10);

ERROR 1222 (21000): The used SELECT statements have a different number of columns

更加严格的是,数据类型上,应该也有要求一致:但是,mysql内部做类型转换处理:要求是能够转换成功;

mysql> (Select t_name,days,c_name from teacher_class where c_name='php0115' order by days limit 10) Union all (Select days,t_name,c_name from teacher_class where c_name='php0228' order by days desc limit 10);

+----------+----------+---------+

| t_name   | days     | c_name  |

+----------+----------+---------+

| 韩é | 15       | php0115 | 

| 李ç | 20       | php0115 | 

| 韩ä | 21       | php0115 | 

| 22       | 李ç | php0228 | 

| 18       | 韩ä | php0228 | 

+----------+----------+---------+

5 rows in set (0.00 sec)

检索结果中的列名称问题:

第一条select语句的列名而定;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息