cmd操作MySQL 范式、单表查询(日记 day 3)

今天记录一下设计范式,还有一些简单的查询操作
先来了解一下范式:

范式是分等级的,越高级的范式限制越多,而且,每条范式总是满足它前面的那些低等级范式

第一范式:
每一列都是不可分割的原子数据项
就比如说,我们寄快递的时候有地址这个字段,那你的地址是不是可以细分,分为省、市、街道等等。这个地址字段就不符合第一范式。原子是什么,就是化学反应不可再分的基本微粒。所以我们要满足第一范式的话,要把地址细分成省、市等等,这些都是构成地址的成分。

你可能会想,市也是省的成分啊?,我查了一些资料,个人理解:
第一范式就如同类与对象的关系,你会定义一个地址类,把省市街道作为地址类的对象,但是你会把市作为省的对象吗,市应该对应省的子类,而不是它的一个属性。

|id  |      address   |
|    |province|city   |
| 1  | 广东   | 广州   |
//这样就出现了冗余,对数据的组织也不好,容易出错

|id  |province|city   |
| 1  | 广东   | 广州   |
//这样方便对数据的操作,比如查广东省的人数这样
//但是也有不好的地方就是我需要一个地址的时候需要拼接数据

第二范式:
满足第一范式的前提下,除主键外每列都必须完全依赖 全部主键,一张表只能有一个主键,可以是单个的也可以是联合的,比如我联合的是id+name,那其他的列必须完全依赖id+name,不能只依赖于id或者name。

创建一张student表,里面有字段class_name 、class_id、 stu_id 、stu_name其中stu_id class_id是联合主键,那么是不是每个class_name都对应着一个class_id,但是不会依赖于学生的id,同样,学生名字也只依赖于学生id,而非课程名字。

|class_name  | class_id | stu_id | stu_name|
primary key(class_id,stu_id) 
//这样就不满足第二范式,就需要将表拆开、分解

//这样分成两个表就满足了第二范式
|class_name  | class_id |

| stu_id | stu_name|

第三范式:
同样第三范式是需满足第二范式的前提,更满足第一范式。
除主键列的其他列不能有传递依赖的关系,其实现实写表的时候是会很容易忽视这点的!
比如:创建一个商品表里面有id,name,price,id能推出name,name可以推出price就叫传递依赖。

/这个表就是有传递依赖关系,id->name,id->price,但是name->price.
|pro_id  |pro_name  |pro_price |
|        |          |          |
//这种情况就得分表

————)
——————————————

接下来是查询
查询操作有很多,但万变不离其宗,只要掌握了规律,学起来就会比较轻松。
要查询我们就先构造一个表:

mysql> select *from student;
+------+-----------+-------+---------------------+---------+
| s_no | s_name    | s_sex | s_birthday          | s_class |
+------+-----------+-------+---------------------+---------+
| 101  | 穆勒      || 1977-09-01 00:00:00 | 95033   |
| 102  | 诺伊尔    || 1975-10-02 00:00:00 | 95031   |
| 103  | 萨利      || 1976-01-23 00:00:00 | 95033   |
| 104  | 莱万      || 1976-02-20 00:00:00 | 95033   |
| 105  | 啊芳      || 1975-02-10 00:00:00 | 95031   |
| 106  | 阿拉巴    || 1974-06-03 00:00:00 | 95031   |
| 107  | 拉姆      || 1976-02-20 00:00:00 | 95033   |
| 108  | 博阿滕    || 1975-02-10 00:00:00 | 95031   |
| 109  | 蒂亚戈    || 1974-06-03 00:00:00 | 95031   |
+------+-----------+-------+---------------------+---------+

先想到的肯定是查表中的所有的东西:select * from 表名; //**就代表所有的

那自然要是想查部分就把 * 代替为某字段,比如查id:select s_no from student;

扫描二维码关注公众号,回复: 11037290 查看本文章
mysql> select s_no from student;
+------+
| s_no |
+------+
| 101  |
| 102  |
| 103  |
| 104  |
| 105  |
| 106  |
| 107  |
| 108  |
| 109  |
+------+

——
1.查询区间数据:
那我想查看103到105的学生的信息:
select * from student where s_no between 103 and 105;
注意:between and 是包含边界的

mysql> select * from student where s_no between 103 and 105;
+------+--------+-------+---------------------+---------+
| s_no | s_name | s_sex | s_birthday          | s_class |
+------+--------+-------+---------------------+---------+
| 103  | 萨利   || 1976-01-23 00:00:00 | 95033   |
| 104  | 莱万   || 1976-02-20 00:00:00 | 95033   |
| 105  | 啊芳   || 1975-02-10 00:00:00 | 95031   |
+------+--------+-------+---------------------+---------+

还有一种方法select * from student where s_no>103 and s_no<105;
当然这种方法也可以取边界值select * from student where s_no>=103 and s_no<=105;

mysql> select * from student where s_no>103 and s_no<105;
+------+--------+-------+---------------------+---------+
| s_no | s_name | s_sex | s_birthday          | s_class |
+------+--------+-------+---------------------+---------+
| 104  | 莱万   || 1976-02-20 00:00:00 | 95033   |
+------+--------+-------+---------------------+---------+

——
2.查询某个数据或者某个数据
给爷查个名字叫萨内的,或者叫穆勒的:
select * from student where s_name in(‘萨内’,‘穆勒’);

mysql> select * from student where s_name in('萨内','穆勒');
+------+--------+-------+---------------------+---------+
| s_no | s_name | s_sex | s_birthday          | s_class |
+------+--------+-------+---------------------+---------+
| 101  | 穆勒   || 1977-09-01 00:00:00 | 95033   |
+------+--------+-------+---------------------+---------+

没有萨内只有穆勒

——
3.查询不同的字段
我在这个表中既想查女性,又想查班级:
select * from student where s_sex=‘女’ or s_class=‘95031’;

mysql> select * from student where s_sex='女' or s_class='95031';
+------+-----------+-------+---------------------+---------+
| s_no | s_name    | s_sex | s_birthday          | s_class |
+------+-----------+-------+---------------------+---------+
| 102  | 诺伊尔    || 1975-10-02 00:00:00 | 95031   |
| 103  | 萨利      || 1976-01-23 00:00:00 | 95033   |
| 105  | 啊芳      || 1975-02-10 00:00:00 | 95031   |
| 106  | 阿拉巴    || 1974-06-03 00:00:00 | 95031   |
| 108  | 博阿滕    || 1975-02-10 00:00:00 | 95031   |
| 109  | 蒂亚戈    || 1974-06-03 00:00:00 | 95031   |
+------+-----------+-------+---------------------+---------+

如果我查询一个不存在的班级是会报错的

mysql> select * from student where s_sex='女' or class='95032';
ERROR 1054 (42S22): Unknown column 'class' in 'where clause'

——
4.查询排序数据
我想让数据排号顺序显示
select * from student order by s_class desc; //降序输出

mysql> select * from student order by s_class desc;
+------+-----------+-------+---------------------+---------+
| s_no | s_name    | s_sex | s_birthday          | s_class |
+------+-----------+-------+---------------------+---------+
| 101  | 穆勒      || 1977-09-01 00:00:00 | 95033   |
| 103  | 萨利      || 1976-01-23 00:00:00 | 95033   |
| 104  | 莱万      || 1976-02-20 00:00:00 | 95033   |
| 107  | 拉姆      || 1976-02-20 00:00:00 | 95033   |
| 102  | 诺伊尔    || 1975-10-02 00:00:00 | 95031   |
| 105  | 啊芳      || 1975-02-10 00:00:00 | 95031   |
| 106  | 阿拉巴    || 1974-06-03 00:00:00 | 95031   |
| 108  | 博阿滕    || 1975-02-10 00:00:00 | 95031   |
| 109  | 蒂亚戈    || 1974-06-03 00:00:00 | 95031   |
+------+-----------+-------+---------------------+---------+

select * from student order by s_class asc; //升序输出

创建了一个分数表

mysql> select * from score;
+------+-------+-----------+
| s_no | c_no  | sc_degree |
+------+-------+-----------+
| 103  | 3-105 |        92 |
| 103  | 3-245 |        86 |
| 103  | 6-166 |        85 |
| 105  | 3-105 |        88 |
| 105  | 3-245 |        75 |
| 105  | 6-166 |        79 |
| 109  | 3-105 |        76 |
| 109  | 3-245 |        68 |
| 109  | 6-166 |        81 |
+------+-------+-----------+

查询以c_no升序.sc_degree降序
注意:数据是先以c_no进行升序,若c_no相同,再以sc_degree降序,有优先级的
select * from score order by c_no asc,sc_degree desc;

mysql> select * from score order by c_no asc,sc_degree desc;
+------+-------+-----------+
| s_no | c_no  | sc_degree |
+------+-------+-----------+
| 103  | 3-105 |        92 |
| 105  | 3-105 |        88 |
| 109  | 3-105 |        76 |
| 103  | 3-245 |        86 |
| 105  | 3-245 |        75 |
| 109  | 3-245 |        68 |
| 103  | 6-166 |        85 |
| 109  | 6-166 |        81 |
| 105  | 6-166 |        79 |
+------+-------+-----------+

——
5.统计数据
统计3-245班的所有学生有多少个:
select count(*) from score where c_no=‘3-245’;

mysql> select  count(*)  from score where c_no='3-245';
+----------+
| count(*) |
+----------+
|        3 |
+----------+

——
6.查询最大值
查询score表中的最高分数的学生号和课程号,有两种方法,一种是子查询,一种是排序。
子查询:select c_no, s_no from score where sc_degree = (select max(sc_degree) from score);
我们来分析一下他的步骤
第一步:找出最大的数据

mysql> select max(sc_degree) from score;
+----------------+
| max(sc_degree) |
+----------------+
|             92 |
+----------------+

第二步:输出其他信息

mysql> select c_no, s_no from score where sc_degree = (select max(sc_degree) from score);
+-------+------+
| c_no  | s_no |
+-------+------+
| 3-105 | 103  |
+-------+------+

排序查询:
select c_no, s_no from score order by sc_degree desc limit 0,1;
limit x,y 表示从第x条数据查y条出来,类似于数组。
注意:再这个栗子中是没有问题当是一旦有多个最高分,只会显示一条

——
7.查询平均成绩
查询每门课的平均成绩:
select c_no,avg(sc_degree) from score group by c_no;
group by 就是分组,将相同的分为一组数据

mysql> select c_no,avg(sc_degree) from score group by c_no;
+-------+----------------+
| c_no  | avg(sc_degree) |
+-------+----------------+
| 3-105 |        85.3333 |
| 3-245 |        76.3333 |
| 6-166 |        81.6667 |
+-------+----------------+

查询至少有2名学生选修的,并且以6开头的课程的平均分
select avg(sc_degree),c_no from score group by c_no having count(c_no) >= 2 and c_no like ‘6%’ ;
解释一下having:过滤的意识,也是一种筛选
where 子句作用于表和视图,having 子句作用于组,配合着group by使用。
而 like '6%'则是模糊查询,就是会自动匹配。

mysql> select avg(sc_degree),c_no  from score group by c_no having count(c_no)>= 2 and c_no like '6%';
+----------------+-------+
| avg(sc_degree) | c_no  |
+----------------+-------+
|        81.6667 | 6-166 |
+----------------+-------+

下篇是多表查询的一些栗子

今天就到这把

发布了12 篇原创文章 · 获赞 9 · 访问量 545

猜你喜欢

转载自blog.csdn.net/weixin_45219512/article/details/105138237