MySQL每周进步一点点——group by去重,与自联结梳理

好久没发表sql学习总结了,今天总结本周新总结的两点:group by去重理解,和自联结的理解。

1、group by去重

从一个例题开始:

已知表格:Product(maker, type, model)

Get the makers who produce only one product type and more than one model. Output: maker, type.

即找出:1个type,>1个model的maker,输出: maker, type

答案:

select distinct maker, type

from Product

where maker in

(select maker from Product

group by maker

having count(distinct type)=1 and count(distinct model)>1);

分析:

① SQL中distinct和group by去重区别:

distinct必须放在开头,将所有查询的字段进行对比,所有字段都完全相同才会去重;

group by 根据字段进行去重,字段相同就会去重。

② 当group by 字段1,字段2,(注意整个表中不止这两个字段),表示数据集中,字段1相等,字段2也相等的数据归为一组,只显示一条数据。那么你可以对字段3进行统计(求和,求平均值等);

对应的,group by 单个字段:这个字段相等的数据将归为一组,只显示一条记录。

③ 理解:group by maker后,type和model都是多个值形成一格,每个不同的maker形成一列,然后用having来进行聚合和筛选。

④ group by 哪个字段,可以select这个字段,不会报错!理解:group by 字段1,查询结果中,字段1会形成单独一列,具有列名!所以,可以被select提取出来。

举例理解:

对于某原表表1,表名为test,想要执行:

select name from test

group by name

MySQL每周进步一点点——group by去重,与自联结梳理

这里是原表test--表一

可是为了能够更好的理解“group by”,建议在思考的过程中,增加一个虚构的中间表:虚拟表3。

MySQL每周进步一点点——group by去重,与自联结梳理

由表一到表三,自己过渡下

1)如果执行select * 的话,那么返回的结果应该是虚拟表3,可是id和number中有的单元格里面的内容是多个值的,而关系数据库就是基于关系的,单元格中是不允许有多个值的,所以你看,执行select * 语句就报错了。

2)再看name列,每个单元格只有一个数据,所以我们select name的话,就没有问题了。

3)那么对于id和number里面的单元格有多个数据的情况怎么办呢?答案就是用聚合函数,聚合函数就用来输入多个数据,输出一个数据的。如cout(id),sum(number),而每个聚合函数的输入就是每一个多数据的单元格。

4)例如我们执行select name,sum(number) from test group by name,那么sum就对虚拟表3的number列的每个单元格进行sum操作,例如对name为aa的那一行的number列执行sum操作,即2+3,返回5,最后执行结果如下:

MySQL每周进步一点点——group by去重,与自联结梳理

5)group by 多个字段该怎么理解呢:如group by name, number

---我们可以把name和number看成一个整体字段,以他们整体来进行分组的。

MySQL每周进步一点点——group by去重,与自联结梳理

如执行

select name,sum(id)

from test

group by name,number

接下来就可以配合select和聚合函数进行操作了,结果如下图:

MySQL每周进步一点点——group by去重,与自联结梳理

2、自联结

不用想什么自联结,自己心里就是两张普通表,就这么简单;

自联结仅仅是个名词,数据库能支持,在语法上没任何区别

举例:原表s,左联结自己(命名为p),采用不同方式联结后,得到的联结表如下,注意,s是主表,p作为副表,只是用于与s匹配;故一对多或者多对一的情况下,p中的每一条,都要与主表s中每一行检索、尽量与主表中每一条匹配。

MySQL每周进步一点点——group by去重,与自联结梳理

这里是原表--表s,也是表p

MySQL每周进步一点点——group by去重,与自联结梳理

MySQL每周进步一点点——group by去重,与自联结梳理

举例说明:

select s.id, s.cate_name, p.cate_name

from tdb_cates s left join tdb_cates p

on s.parent_id=p.id;

select之后,呈现输出的结果:

MySQL每周进步一点点——group by去重,与自联结梳理

输出的结果

好了,祝大家SQL学习愉快!


分享到:


相關文章: