PHP之MySQL笔记3

22 篇文章 2 订阅
10 篇文章 0 订阅

1 补充

1.1 插入数据时主键冲突

-- 插入测试表
mysql> create table stu(
    -> id char(4) primary key,
    -> name varchar(20)
    -> )engine=innodb;
Query OK, 0 rows affected (0.06 sec)

-- 插入测试数据
mysql> insert into stu values ('s001','tom');
Query OK, 1 row affected (0.00 sec)

如果插入的主键重复会报错

解决方法:如果插入的主键重复就执行替换

语法一:

mysql> replace into stu values('s002','ketty');
Query OK, 2 rows affected (0.00 sec)
# 原理:如果插入的主键不重复就直接插入,如果主键重复就替换(删除原来的记录,插入新记录)

语法二(推荐):

on duplicate key update # 当插入的值与主键或唯一键有冲突执行update操作
-- 例题
mysql> insert into stu values ('s002','李白') on duplicate key update name='李白';
Query OK, 2 rows affected (0.00 sec)
# 插入的数据和主键或唯一键起冲突,将s002的name字段改为‘李白’

2.实体之间的关系

在这里插入图片描述

2.1 一对多(1:N)

主表中的一条记录对应从表中的多条记录
在这里插入图片描述

实现一对多的方式:主键和非主键建立关系

问题:说出几个一对多的关系?

班主任表--学生表
品牌表--商品表

2.2 多对一(N:1)

多对一就是一对多

2.3 一对一(1:1)

在这里插入图片描述

如何实现一对一:主键和主键建立关系

思考:一对一两个表完全可以用一个表实现,为什么还要分成两个表?

答:在字段数量很多的情况下,数据量也就很大,每次查询都需要检索大量数据,这样效率低下。
我们可以将所有字段分成两个部分,“常用字段”和“不常用字段”,这样对大部分查询者来说效率就提高了
【表的垂直分割】

2.4 多对多(N:M)

主表中的一条记录对应从表中的多条激励,从表中的一条记录,对应主表中的多条记录

在这里插入图片描述

如何实现多对多:利用第三张关系表

问题:说出几个多对多的关系

讲师表--学生表
课程表--学生表
商品表--订单表

小结:

1、实现一对一:主键和主键建立关系
2、实现一对多:主键和非主键建立关系
3、实现多对多:引入第三张关系表

3 数据库设计

3.1 数据库设计的步骤

  1. 收集信息:与该系统有关人员进行交流、坐谈,充分理解数据库需要完成的任务

  2. 标识对象(实体-Entity):标识数据库要管理的关键对象或实体

  3. 标识每个实体的属性(Attribute)

  4. 标识对象之间的关系(Relationship)

  5. 将模型转换成数据库

  6. 规范化


3.2 例题

第一步:收集信息

BBS论坛的基本功能:
用户注册和登录,后台数据库需要存放用户的注册信息和在线状态信息;
用户发贴,后台数据库需要存放贴子相关信息,如贴子内容、标题等;
用户可以对发帖进行回复;
论坛版块管理:后台数据库需要存放各个版块信息,如版主、版块名称、贴子数等;

第二步:标识对象

实体一般是名词:
1、用户对象
2、板块对象
3、帖子对象
4、跟帖对象

第三步:标识每个实体的属性

在这里插入图片描述

第四步:标识对象之间的关系

3.3 绘制E-R图

E-R(Entity-Relationship)实体关系图)

在这里插入图片描述

在这里插入图片描述

完整的E-R图

在这里插入图片描述

3.4 将E-R图转成表

  1. 实体转成表,属性转成字段

  2. 如果没有合适的字段做主键,给表添加一个自动增长列做主键。

4 数据模范化

4.1 第一范式:确保每列原则性

第一范式:目标是确保每列的原子性,一个字段表示一个含义

在这里插入图片描述
思考如下表是否满足第一范式

在这里插入图片描述
思考:地址包含省、市、县、地区是否需要拆分?

答:如果仅仅起地址作用,不需要统计,可以不拆分;如果有按地区统计的功能需要拆分

在实际项目中,建议拆分。

4.2 第二范式:非键字段必须依赖于键字段

第二范式:在满足第一范式的前提下,要求每个表只描述一件事情。
在这里插入图片描述
思考如下表设计是否合理

在这里插入图片描述

4.3 第三范式:消除传递依赖

第三范式:在满足第二范式的前提下,除了主键以外的其他列消除传递依赖

在这里插入图片描述
思考如下表设计是否合理?

在这里插入图片描述
结论:不满足第三范式,因为语文和数学确定了,总分就确定了

4.4 反3nf

范式越高,数据冗余越少,表会越来越多,但是效率有时就越低下,为了提高运行效率,可以适当让数据冗余

学号姓名语文数学总分
1李白7788165

上面的设计不满足第三范式,但是高考分数表就是要这样设计的,为什么?

答:高考分数峰值访问量非常大,这时候就是性能更重要。当性能和规范化冲突的时候,我们首选性能。这就是“反三范式”。

小结

1、第一范式约束的是所有字段

2、第二范式约束的是主键和非主键的关系

3、第三范式约束的是非主键之间的关系

4、范式越高,冗余越少,但表也越多。

5、规范化和性能的关系 :性能比规范化更重要

4.5 例题

需求

假设某建筑公司要设计一个数据库。公司的业务规
则概括说明如下:
公司承担多个工程项目,每一项工程有:工程号、工程名称、施工人员等
公司有多名职工,每一名职工有:职工号、姓名、性别、职务(工程师、技术员)等
公司按照工时和小时工资率支付工资,小时工资率由职工的职务决定(例如,技术员的小时工资率与工程师不同)

标识实体

1、工程
2、职工
3、工时
4、小时工资率

在这里插入图片描述

5 查询语句

语法:select [选项] 列名 [from 表名] [where 条件]  [group by 分组] [order by 排序][having 条件] [limit 限制]

5.1 字段表达式

-- 可以直接输出内容
mysql> select '锄禾日当午';
+------------+
| 锄禾日当午          |
+------------+
| 锄禾日当午          |
+------------+
1 row in set (0.00 sec)

-- 输出表达式
mysql> select 10*10;
+-------+
| 10*10 |
+-------+
|   100 |
+-------+
1 row in set (0.00 sec)

mysql> select ch,math,ch+math from stu;
+------+------+---------+
| ch   | math | ch+math |
+------+------+---------+
|   80 | NULL |    NULL |
|   77 |   76 |     153 |
|   55 |   82 |     137 |
| NULL |   74 |    NULL |


-- 表达式部分可以用函数
mysql> select rand();
+--------------------+
| rand()             |
+--------------------+
| 0.6669325378415478 |
+--------------------+
1 row in set (0.00 sec)
mysql> select '锄禾日当午' as '标题';   -- 取别名
+------------+
| 标题           |
+------------+
| 锄禾日当午          |
+------------+
1 row in set (0.00 sec)

mysql> select ch,math,ch+math as '总分' from stu;
+------+------+------+
| ch   | math | 总分    |
+------+------+------+
|   80 | NULL | NULL |
|   77 |   76 |  153 |
|   55 |   82 |  137 |
| NULL |   74 | NULL |

-- 多学一招:as可以省略
mysql> select ch,math,ch+math '总分' from stu;
+------+------+------+
| ch   | math | 总分    |
+------+------+------+
|   80 | NULL | NULL |
|   77 |   76 |  153 |
|   55 |   82 |  137 |
| NULL |   74 | NULL |

5.2 from子句

from:来自,from后面跟的是数据源。数据源有多个时,返回的是笛卡尔积


插入测试表

create table t1(
       str char(2)
);
insert into t1 values ('aa'),('bb');
create table t2(
       num int
);
insert into t2 values (10),(20);

测试:

-- from子句
mysql> select * from t1;
+------+
| str  |
+------+
| aa   |
| bb   |
+------+
2 rows in set (0.00 sec)

-- 多个数据源,返回笛卡尔积
mysql> select * from t1,t2;
+------+------+
| str  | num  |
+------+------+
| aa   |   10 |
| bb   |   10 |
| aa   |   20 |
| bb   |   20 |
+------+------+
4 rows in set (0.00 sec)

5.3 dual表

dual表是一个伪表。在有些特定情况下,没有具体的表的参与,但是为了保证select语句的完整又必须要一个表名,这时候就使用伪表。

mysql> select 10*10 as 结果 from dual;
+------+
| 结果     |
+------+
|  100 |
+------+
1 row in set (0.00 sec)

5.4 where子句

where后面跟的是条件,在数据源中进行筛选。返回条件为真记录

MySQL支持的运算符

-- 比较运算符
>	大于
<	小于
>=	大于等于
<=	小于等于
=	等于
!=	不等于

-- 逻辑运算符
and  与
or   或
not  非

-- 其他
in | not in	 					 字段的值在枚举范围内
between…and|not between…and      字段的值在数字范围内
is null | is not null			 字段的值不为空

例题:

-- 查找语文成绩及格的学生
mysql> select * from stu where ch>=60;
-- 查询语文和数学都及格的学生
mysql> select * from stu where ch>=60 and math>=60;
-- 查询语文或数学不及格的学生
mysql> select * from stu where ch<60 or math<60;

思考:如下语句输出什么?
mysql> select * from stu where 1;		-- 输出所有数据
mysql> select * from stu where 0;		-- 不输出数据

思考:如何查找北京和上海的学生

-- 通过or实现
mysql> select * from stu where stuaddress='北京' or stuaddress='上海';

-- 通过in语句实现
mysql> select * from stu where stuaddress in ('北京','上海');

-- 查询不是北京和上海的学生
mysql> select * from stu where stuaddress not in ('北京','上海');

思考:查找年龄在20~25之间

-- 方法一:
mysql> select * from stu where stuage>=20 and stuage<=25;

-- 方法二:
mysql> select * from stu where not(stuage<20 or stuage>25);

-- 方法三:between...and...
mysql> select * from stu where stuage between 20 and 25;

-- 年龄不在20~25之间
mysql> select * from stu where stuage not between 20 and 25;

思考:

-- 查找缺考的学生
mysql> select * from stu where ch is null or math is null;
+--------+----------+--------+--------+---------+------------+------+------+
| stuNo  | stuName  | stuSex | stuAge | stuSeat | stuAddress | ch   | math |
+--------+----------+--------+--------+---------+------------+------+------+
| s25301 | 张秋丽         ||     18 |       1 | 北京           |   80 | NULL |
| s25304 | 欧阳俊雄        ||     28 |       4 | 天津           | NULL |   74 |
+--------+----------+--------+--------+---------+------------+------+------+

-- 查找没有缺考的学生
mysql> select * from stu where ch is not null and math is not null;
+--------+----------+--------+--------+---------+------------+------+------+
| stuNo  | stuName  | stuSex | stuAge | stuSeat | stuAddress | ch   | math |
+--------+----------+--------+--------+---------+------------+------+------+
| s25302 | 李文才        ||     31 |       3 | 上海          |   77 |   76 |
| s25303 | 李斯文        ||     22 |       2 | 北京           |   55 |   82 |
| s25305 | 诸葛丽丽         ||     23 |       7 | 河南           |   72 |   56 |
| s25318 | 争青小子        ||     26 |       6 | 天津           |   86 |   92 |
| s25319 | 梅超风        ||     23 |       5 | 河北          |   74 |   67 |
| s25320 | Tom      ||     24 |       8 | 北京           |   65 |   67 |
| s25321 | Tabm     ||     23 |       9 | 河北          |   88 |   77 |
+--------+----------+--------+--------+---------+------------+------+------+
7 rows in set (0.00 sec)

-- 查找需要补考的学生
mysql> select * from stu where ch<60 or math<60 or ch is null or math is null;
+--------+----------+--------+--------+---------+------------+------+------+
| stuNo  | stuName  | stuSex | stuAge | stuSeat | stuAddress | ch   | math |
+--------+----------+--------+--------+---------+------------+------+------+
| s25301 | 张秋丽         ||     18 |       1 | 北京           |   80 | NULL |
| s25303 | 李斯文        ||     22 |       2 | 北京           |   55 |   82 |
| s25304 | 欧阳俊雄        ||     28 |       4 | 天津           | NULL |   74 |
| s25305 | 诸葛丽丽         ||     23 |       7 | 河南           |   72 |   56 |
+--------+----------+--------+--------+---------+------------+------+------+
4 rows in set (0.00 sec)

练习:

-- 1、查找学号是s25301,s25302,s25303的学生
mysql> select * from stu where stuno in ('s25301','s25302','s25303');
+--------+---------+--------+--------+---------+------------+------+------+
| stuNo  | stuName | stuSex | stuAge | stuSeat | stuAddress | ch   | math |
+--------+---------+--------+--------+---------+------------+------+------+
| s25301 | 张秋丽        ||     18 |       1 | 北京           |   80 | NULL |
| s25302 | 李文才       ||     31 |       3 | 上海          |   77 |   76 |
| s25303 | 李斯文       ||     22 |       2 | 北京           |   55 |   82 |
+--------+---------+--------+--------+---------+------------+------+------+
3 rows in set (0.00 sec)

-- 2、查找年龄是18~20的学生
mysql> select * from stu where stuage between 18 and 20;
+--------+---------+--------+--------+---------+------------+------+------+
| stuNo  | stuName | stuSex | stuAge | stuSeat | stuAddress | ch   | math |
+--------+---------+--------+--------+---------+------------+------+------+
| s25301 | 张秋丽        ||     18 |       1 | 北京           |   80 | NULL |
+--------+---------+--------+--------+---------+------------+------+------+
1 row in set (0.00 sec)

5.5 group by 【分组查询】

将查询的结果分组,分组查询目的在于统计数据。

-- 查询男生和女生的各自语文平均分
mysql> select stusex,avg(ch) '平均分' from stu group by stusex;
+--------+---------+
| stusex | 平均分       |
+--------+---------+
|| 72.2500 |
|| 77.0000 |
+--------+---------+
2 rows in set (0.00 sec)

-- 查询男生和女生各自多少人
mysql> select stusex,count(*) 人数 from stu group by stusex;
+--------+------+
| stusex | 人数     |
+--------+------+
||    4 |
||    5 |
+--------+------+
2 rows in set (0.00 sec)

-- 查询每个地区多少人
mysql> select stuaddress,count(*) from stu group by stuaddress;
+------------+----------+
| stuaddress | count(*) |
+------------+----------+
| 上海          |        1 |
| 北京           |        3 |
| 天津           |        2 |
| 河北          |        2 |
| 河南           |        1 |
+------------+----------+
5 rows in set (0.00 sec)

-- 每个地区的数学平均分
mysql> select stuaddress,avg(math) from stu group by stuaddress;
+------------+-----------+
| stuaddress | avg(math) |
+------------+-----------+
| 上海          |   76.0000 |
| 北京           |   74.5000 |
| 天津           |   83.0000 |
| 河北          |   72.0000 |
| 河南           |   56.0000 |
+------------+-----------+
5 rows in set (0.00 sec)

查询字段是普通字段,只取第一个值

在这里插入图片描述

通过group_concat()函数将同一组的值连接起来显示

mysql> select group_concat(stuname),stusex,avg(math) from stu group by stusex;
+-------------------------------------+--------+-----------+
| group_concat(stuname)               | stusex | avg(math) |
+-------------------------------------+--------+-----------+
| 李斯文,诸葛丽丽,梅超风,Tabm             ||   70.5000 |
| 张秋丽,李文才,欧阳俊雄,争青小子,Tom      ||   77.2500 |
+-------------------------------------+--------+-----------+
2 rows in set (0.00 sec)

多列分组

mysql> select stuaddress,stusex,avg(math) from stu group by stuaddress,stusex;
+------------+--------+-----------+
| stuaddress | stusex | avg(math) |
+------------+--------+-----------+
| 上海          ||   76.0000 |
| 北京           ||   82.0000 |
| 北京           ||   67.0000 |
| 天津           ||   83.0000 |
| 河北          ||   72.0000 |
| 河南           ||   56.0000 |
+------------+--------+-----------+
6 rows in set (0.00 sec)

小结:

1、如果是分组查询,查询字段是分组字段和聚合函数。
2、查询字段是普通字段,只取第一个值
3、group_concat()将同一组的数据连接起来

5.6 order by排序

asc:升序【默认】
desc:降序

-- 按年龄的升序排列
mysql> select * from stu order by stuage asc;
mysql>  select * from stu order by stuage;       -- 默认是升序

-- 按总分降序
mysql> select *,ch+math '总分' from stu order by ch+math desc;

多列排序

-- 年龄升序,如果年龄一样,按ch降序排列
mysql> select * from stu order by stuage asc,ch desc;

思考如下代码表示什么含义

select * from stu order by stuage desc,ch desc;     #年龄降序,语文降序
select * from stu order by stuage desc,ch asc;		#年龄降序,语文升序
select * from stu order by stuage,ch desc;          #年龄升序、语文降序
select * from stu order by stuage,ch; 				#年龄升序、语文升序

5.7 having条件

having:是在结果集上进行条件筛选

例题

-- 查询女生
mysql> select * from stu where stusex='女';
+--------+----------+--------+--------+---------+------------+------+------+
| stuNo  | stuName  | stuSex | stuAge | stuSeat | stuAddress | ch   | math |
+--------+----------+--------+--------+---------+------------+------+------+
| s25303 | 李斯文        ||     22 |       2 | 北京           |   55 |   82 |
| s25305 | 诸葛丽丽         ||     23 |       7 | 河南           |   72 |   56 |
| s25319 | 梅超风        ||     23 |       5 | 河北          |   74 |   67 |
| s25321 | Tabm     ||     23 |       9 | 河北          |   88 |   77 |
+--------+----------+--------+--------+---------+------------+------+------+
4 rows in set (0.00 sec)

-- 查询女生
mysql> select * from stu having stusex='女';
+--------+----------+--------+--------+---------+------------+------+------+
| stuNo  | stuName  | stuSex | stuAge | stuSeat | stuAddress | ch   | math |
+--------+----------+--------+--------+---------+------------+------+------+
| s25303 | 李斯文        ||     22 |       2 | 北京           |   55 |   82 |
| s25305 | 诸葛丽丽         ||     23 |       7 | 河南           |   72 |   56 |
| s25319 | 梅超风        ||     23 |       5 | 河北          |   74 |   67 |
| s25321 | Tabm     ||     23 |       9 | 河北          |   88 |   77 |
+--------+----------+--------+--------+---------+------------+------+------+
4 rows in set (0.00 sec)

-- 查询女生姓名
mysql> select stuname from stu where stusex='女';
+----------+
| stuname  |
+----------+
| 李斯文        |
| 诸葛丽丽         |
| 梅超风        |
| Tabm     |
+----------+
4 rows in set (0.00 sec)

-- 使用having报错,因为结果集中没有stusex字段
mysql> select stuname from stu having stusex='女';
ERROR 1054 (42S22): Unknown column 'stusex' in 'having clause'

小结:

having和where的区别:
where是对原始数据进行筛选,having是对记录集进行筛选。

5.8 limit

语法:limit [起始位置],显示长度

-- 从第0个位置开始取,取3条记录
mysql> select * from stu limit 0,3;

-- 从第2个位置开始取,取3条记录
mysql> select * from stu limit 2,3;
+--------+----------+--------+--------+---------+------------+------+------+
| stuNo  | stuName  | stuSex | stuAge | stuSeat | stuAddress | ch   | math |
+--------+----------+--------+--------+---------+------------+------+------+
| s25303 | 李斯文        ||     22 |       2 | 北京           |   55 |   82 |
| s25304 | 欧阳俊雄        ||     28 |       4 | 天津           | NULL |   74 |
| s25305 | 诸葛丽丽         ||     23 |       7 | 河南           |   72 |   56 |
+--------+----------+--------+--------+---------+------------+------+------+
3 rows in set (0.00 sec)

起始位置可以省略,默认是从0开始

mysql> select * from stu limit 3;
+--------+---------+--------+--------+---------+------------+------+------+
| stuNo  | stuName | stuSex | stuAge | stuSeat | stuAddress | ch   | math |
+--------+---------+--------+--------+---------+------------+------+------+
| s25301 | 张秋丽        ||     18 |       1 | 北京           |   80 | NULL |
| s25302 | 李文才       ||     31 |       3 | 上海          |   77 |   76 |
| s25303 | 李斯文       ||     22 |       2 | 北京           |   55 |   82 |
+--------+---------+--------+--------+---------+------------+------+------+
3 rows in set (0.00 sec)

例题:找出班级总分前三名

mysql> select *,ch+math total from stu order by (ch+math) desc limit 0,3;
+--------+----------+--------+--------+---------+------------+------+------+-------+
| stuNo  | stuName  | stuSex | stuAge | stuSeat | stuAddress | ch   | math | total |
+--------+----------+--------+--------+---------+------------+------+------+-------+
| s25318 | 争青小子   ||     26 |       6 | 天津           |   86 |   92 |   178 |
| s25321 | Tabm     ||     23 |       9 | 河北          |   88 |   77 |   165 |
| s25302 | 李文才    ||     31 |       3 | 上海          |   77 |   76 |   153 |
+--------+----------+--------+--------+---------+------------+------+------+-------+
3 rows in set (0.00 sec)

多学一招:limit在update和delete语句中也是可以使用的。

-- 	前3名语文成绩加1分
mysql> update stu set ch=ch+1 order by ch+math desc limit 3;
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3  Changed: 3  Warnings: 0

-- 前3名删除
mysql> delete from stu order by ch+math desc limit 3;
Query OK, 3 rows affected (0.00 sec)

5.9 查询语句中的选项

查询语句中的选项有两个:

1、 all:显示所有数据 【默认】

2、 distinct:去除结果集中重复的数据

mysql> select all stuaddress from stu;
+------------+
| stuaddress |
+------------+
| 北京           |
| 北京           |
| 天津           |
| 河南           |
| 河北          |
| 北京           |
+------------+
6 rows in set (0.00 sec)

-- 去除重复的项
mysql> select distinct stuaddress from stu;
+------------+
| stuaddress |
+------------+
| 北京           |
| 天津           |
| 河南           |
| 河北          |
+------------+
4 rows in set (0.00 sec)

6 聚合函数

  1. sum() 求和
  2. avg() 求平均值
  3. max() 求最大值
  4. min() 求最小值
  5. count() 求记录数
# 语文最高分
mysql> select max(ch) '语文最大值' from stu;
+------------+
| 语文最大值          |
+------------+
|         88 |
+------------+
1 row in set (0.00 sec)

#求语文总分、语文平均分、语文最低分、总人数

mysql> select max(ch) 语文最高分,min(ch) 语文最低分,sum(ch) 语文总分,avg(ch) 语文平均分,count(*) 总人数 from stu;
+------------+------------+----------+------------+--------+
| 语文最高分  | 语文最低分   | 语文总分   | 语文平均分  | 总人数  |
+------------+------------+----------+------------+--------+
|         88 |         55 |      597 |    74.6250 |      9 |
+------------+------------+----------+------------+--------+
1 row in set (0.00 sec)

7 模糊查询

7.1 通配符

  1. _ [下划线] 表示任意一个字符
  2. % 表示任意字符

练习

> 1、满足“T_m”的有(A、C)
A:Tom         B:Toom       C:Tam         D:Tm     E:Tmo

2、满足“T_m_”的有( B C)
A:Tmom   B:Tmmm  C:T1m2    D:Tmm     E:Tm

3、满足“张%”的是(ABCD)
A:张三     B:张三丰     C:张牙舞爪      D:张      E:小张

4、满足“%诺基亚%”的是(ABCD)
A:诺基亚2100   B:2100诺基亚   C:把我的诺基亚拿过来   D:诺基亚

7.2 模糊查询(like)

模糊查询的条件不能用’=’,要使用like。

mysql> select * from stu where stuname like 'T_m';
+--------+---------+--------+--------+---------+------------+------+------+
| stuNo  | stuName | stuSex | stuAge | stuSeat | stuAddress | ch   | math |
+--------+---------+--------+--------+---------+------------+------+------+
| s25320 | Tom     ||     24 |       8 | 北京           |   65 |   67 |
+--------+---------+--------+--------+---------+------------+------+------+
1 row in set (0.00 sec)

-- 查询姓张的学生
mysql> select * from stu where stuname like '张%';
+--------+---------+--------+--------+---------+------------+------+------+
| stuNo  | stuName | stuSex | stuAge | stuSeat | stuAddress | ch   | math |
+--------+---------+--------+--------+---------+------------+------+------+
| s25301 | 张秋丽   ||     18 |       1 | 北京        |   80 | NULL |
+--------+---------+--------+--------+---------+------------+------+------+
1 row in set (0.00 sec)

8 union(联合)

插入测试数据

create table emp(
       id tinyint unsigned auto_increment primary key,
       name varchar(20) not null,
       skill set('PHP','mysql','java')
 );
 
insert into emp values (null,'李白',1),(null,'杜甫',2),(null,'白居易',4)
insert into emp values (null,'争青小子',3)

8.1 union的使用

作用:将多个select语句结果集纵向联合起来

语法:select 语句 union [选项] select 语句 union [选项] select 语句
-- 查询stu表中的姓名和emp表中姓名 结果自动合并的重复的记录
mysql> select stuname from stu union select name from emp;

例题:查询上海的男生和北京的女生

-- 方法一:
mysql> select * from stu where (stuaddress='上海' and stusex='男') or (stuaddress='北京' and stusex='女');
+--------+---------+--------+--------+---------+------------+------+------+
| stuNo  | stuName | stuSex | stuAge | stuSeat | stuAddress | ch   | math |
+--------+---------+--------+--------+---------+------------+------+------+
| s25302 | 李文才       ||     31 |       3 | 上海          |   77 |   76 |
| s25303 | 李斯文       ||     22 |       2 | 北京           |   55 |   82 |
+--------+---------+--------+--------+---------+------------+------+------+
2 rows in set (0.00 sec)

-- 方法二:union
mysql> select * from stu where stuaddress='上海' and stusex='男' union select * from stu where stuaddress='北京' and stusex='女';
+--------+---------+--------+--------+---------+------------+------+------+
| stuNo  | stuName | stuSex | stuAge | stuSeat | stuAddress | ch   | math |
+--------+---------+--------+--------+---------+------------+------+------+
| s25302 | 李文才       ||     31 |       3 | 上海          |   77 |   76 |
| s25303 | 李斯文       ||     22 |       2 | 北京           |   55 |   82 |
+--------+---------+--------+--------+---------+------------+------+------+
2 rows in set (0.00 sec)

结论:union可以将一个复杂的条件转成两个简单的条件

8.2 union的选项

union的选项有两个

1、 all:显示所有数据

2、 distinct:去除重复的数据【默认】

mysql> select stuname from stu union all select name from emp;

8.3 union的注意事项

1、 union两边的select语句的字段个数必须一致

2、 union两边的select语句的字段名可以不一致,最终按第一个select语句的字段名。

3、 union两边的select语句中的数据类型可以不一致。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
主要包含最基础的数据库语句,很适合初学者,目标使用企业管理器创建数据库表设置表的主键、外键和建立表之间的关系为表增加约束数据完整性 数据完整性 数据存放在表中 “数据完整性的问题大多是由于设计引起的” 创建表的时候,就应当保证以后数据输入是正确的 ——误的数据、不符合要求的数据不允许输入完整性包括… 输入的类型是否正确? ——年龄必须是数字输入的格式是否正确? ——身份证号码必须是18位是否在允许的范围内? ——性别只能是”男”或者”女” 是否存在重复输入? ——学员信息输入了两次是否符合其他特定要求? ——信誉值大于5的用户才能够加入会员列表 …… 完整性包括… 实体完整性域完整性引用完整性自定义完整性表操作创建数据库表 SQL Server的数据类型思考创建数据库表思考创建数据库表思考选择主键的原则创建数据库表思考创建数据库表创建数据库表关系图主表和从表创建数据库表-7 创建数据库表完毕!导入-导出数据总结 SQL Server创建表的过程饰淦麈定数据列的属性的过程,同时也是实施数据完整性(包括实体完整性、引用完整性和域完整性等)保证的过程实体完整性数据行不能存在重复,引用完整性要求子表中的相关项必须在主表中存在域完整性实现了对输入到特定列的数值的限制 SQL Server中存在五种约束,分别是:主键约束、外键约束、检查约束、默认约束和唯一性约束(唯一性约束将在后续课程中使用SQL语句实现)总结创建数据库表需要:确定表的列名、数据类型、是否允许为空,还需要确定主键、必要的默认值、标识列和检查约束如果建立了主表和子表的关系,则: ——子表中的相关项目的数据,在主表中必须存在; ——主表中相关项的数据更改了,则子表对应的数据项也应当随之 更改; ——在删除子表之前,不能够删除主表;回顾SQL Server的约束约束的目的:确保表中数据的完整型常用的约束类型:主键约束(Primary Key Constraint):要求主键列数据唯一,并且不允许为空唯一约束(Unique Constraint):要求该列唯一,允许为空,但只能出现一个空值。检查约束(Check Constraint):某列取值范围限制、格式限制等,如有关年龄的约束默认约束(Default Constraint):某列的默认值,如我们的男性学员较多,性别默认为“男” 外键约束(Foreign Key Constraint):用于两表间建立关系,需要指定引用主表的那列添加约束 添加约束的语法:添加约束示例添加约束示例删除约束如果误地添加了约束,我们还可以删除约束 删除约束的语法第二部分 数据库的设计课程目标了解设计数据库的基本步骤熟练使用T-SQL实现建库、建表、加约束掌握T-SQL编程,实现功能强大的查询掌握创建索引、视图,快速访问数据库 掌握创建存储过程,实现复杂的业务规则理解触发器的原理,实现高级的约束目标了解设计数据库的步骤掌握如何绘制数据库的E-R图理解数据库的规范化-三大范式为什么需要设计数据库 2-1 为什么需要设计数据库 2-2 软件项目开发周期需求分析阶段:分析客户的业务和数据处理需求; 概要设计阶段:设计数据库的E-R模型图,确认需求信息 的正确和完整; 详细设计阶段:将E-R图转换为多张表,进行逻辑设计, 并应用数据库设计的三大范式进行审核; 代码编写阶段:选择具体数据库进行物理实现,并编写 代码实现前端应用; 软件测试阶段:…… 安装部署:…… 设计数据库的步骤4-1 收集信息: 与该系统有关人员进行交流、坐谈,充分理解数据库需要完成的任务 设计数据库的步骤4-2 标识对象(实体-Entity) 标识数据库要管理的关键对象或实体 设计数据库的步骤4-3 设计数据库的步骤4-4 标识对象之间的关系(Relationship) 绘制E-R图 4-1 E-R(Entity-Relationship)实体关系图 绘制E-R图 4-2 绘制E-R图 4-3 映射基数绘制E-R图如何将E-R图转换为表 3-1 如何将E-R图转换为表 3-2 如何将E-R图转换为表数据规范化 仅有好的RDBMS并不足以避免数据冗余,必须在数据库的设计中创建好的表结构 Dr E.F.codd 最初定义了规范化的三个级别,范式是具有最小冗余的表结构。这些范式是:第一范式(1st NF -First Normal Fromate) 第二范式(2nd NF-Second Normal Fromate) 第三范式(3rd NF- Third Normal Fromate) 第一范式 (1st NF) 第二范式 (2nd NF) 第三范式 (3rd NF) 规范化实例 5-1 假设某建筑公司要设计一个数据库。公司的业务规则概括说明如下:公司承担多个工程项目,每一项工程有:工程号、工程名称、施工人员等公司有多名职工,每一名职工有:职工号、姓名、性别、职务(工程师、技术员)等公司按照工时和小时工资率支付工资,小时工资率由职工的职务决定(例如,技术员的小时工资率与工程师不同)公司定期制定一个工资报表,如图-1所示规范化实例 5-2 规范化实例 5-3 规范化实例 5-4 1.表中包含大量的冗余,可能会导致数据异常:更新异常 例如,修改职工号=1001的职务,则必须修改所有职工号=1001的行添加异常 若要增加一个新的职工时,首先必须给这名职工分配一个工程。或者为了添加一名新职工的数据,先给这名职工分配一个虚拟的工程。(因为主关键字不能为空)删除异常 例如,1001号职工要辞职,则必须删除所有职工号=1001的数据行。这样的删除操作,很可能丢失了其它有用的数据规范化实例 5-5 2.采用这种方法设计表的结构,虽然很容易产生工资报表,但是每当一名职工分配一个工程时,都要重复输入大量的数据。这种重复的输入操作,很可能导致数据的不一致性。 应用范式规范化设计应用第二范式规范化应用第三范式规范化规范化和性能的关系 总结 2-1 在需求分析阶段,设计数据库的一般步骤为:收集信息标识对象标识每个对象的属性标识对象之间的关系在概要设计阶段和详细设计阶段,设计数据库的步骤为:绘制E-R图将E-R图转换为表格应用三大范式规范化表格总结 2-2 为了设计结构良好的数据库,需要遵守一些专门的规则,称为数据库的设计范式 。第一范式(1NF)的目标:确保每列的原子性。第二范式(2NF)的目标:确保表中的每列,都和主键相关 第三范式(3NF)的目标:确保每列都和主键列直接相关,而不是间接相关 第三部分 常用的SQL语法及技巧查询-单表查询 SELECT <选择列表> FROM [[<数据库名>.]<模式名>.]<基表名> | <视图名> <相关名> [
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值