龙空技术网

如何零基础入门MySQL?

Java杂谈 210

前言:

而今大家对“mysql入门很简单”大概比较讲究,咱们都想要了解一些“mysql入门很简单”的相关内容。那么小编在网上网罗了一些对于“mysql入门很简单””的相关文章,希望看官们能喜欢,朋友们一起来了解一下吧!

hello早上好啊!有小伙伴看留言小编说小编发的文章太难了!那么这一篇文章里,就主要讲讲group by的一些技巧,以及子查询。

以下内容都是不能不掌握的。

大家读完文章一定要多练习子查询哦!

本文将用以下数据做演示

这份数据可以看到,这次我们的条数变多了,我们将专门来做Group By操作。

首先来解释以下,什么是group by,什么样的数据会被分组,为什么要被分组。

比如最常见的需求,看看每个门派各有多少人,我们会希望有一份这样的结果:

select 门派, 人数

那我们看看怎么做呢?

首先把下面代码用键盘复制(不要用鼠标)到网页左边,点击Build Schemal

CREATE TABLE `student_info` (

`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id,主键',

`student_name` varchar(50) COMMENT '学生姓名',

`student_age` int COMMENT '学生年龄',

`student_sex` varchar(10) COMMENT '学生性别',

`student_class` varchar(10) COMMENT '门派',

PRIMARY KEY (`id`)

);

INSERT INTO `student_info`

(`student_name`, `student_age`,`student_sex`, `student_class`)

VALUES

('葛尧', 8 , '男', '木叶')

;

INSERT INTO `student_info`

(`student_name`, `student_age`,`student_sex`, `student_class`)

VALUES

('令狐冲', 15 , '男', '华山派')

;

INSERT INTO `student_info`

(`student_name`, `student_age`,`student_sex`, `student_class`)

VALUES

('林平之', 19 , '男', '福威镖局')

;

INSERT INTO `student_info`

(`student_name`, `student_age`,`student_sex`, `student_class`)

VALUES

('岳不群', 40 , '男', '华山派')

;

INSERT INTO `student_info`

(`student_name`, `student_age`,`student_sex`, `student_class`)

VALUES

('林震南', 45 , '男', '福威镖局')

;

INSERT INTO `student_info`

(`student_name`, `student_age`,`student_sex`, `student_class`)

VALUES

('林夫人', 43 , '女', '福威镖局')

;

INSERT INTO `student_info`

(`student_name`, `student_age`,`student_sex`, `student_class`)

VALUES

('小师妹', 14 , '女', '华山派')

;

INSERT INTO `student_info`

(`student_name`, `student_age`,`student_sex`, `student_class`)

VALUES

('仪琳', 18 , '女', '恒山派')

;

INSERT INTO `student_info`

(`student_name`, `student_age`,`student_sex`, `student_class`)

VALUES

('曲菲菲', 13 , '女', '木叶')

;

INSERT INTO `student_info`

(`student_name`, `student_age`,`student_sex`, `student_class`)

VALUES

('任盈盈', 14 , '女', '魔教')

;

用键盘复制到:

SQL Fiddle | A tool for easy online testing and sharing of database problems and their solutions.

​左边,点击Build Shcema

之后,在右边的框框来进行我们的SQL的书写:

SELECT

`student_class` as '门派',

count(1) as '人数'

FROM

`student_info`

GROUP BY

`student_class`

ORDER BY

`人数` DESC

;

点击Run SQL

结果如下:

门派人数统计

ok,结果是对的,但让我们来观察这一段SQL

1,Select的2个值

列`studnet_class`,他出现在了group by语句中,意思是,1个组内所有元素,他们的这一列属性都相同——这10条数据根据各自的`student_class`分成了5组,每个组内元素个数各有不同,但他们都有相同的student_class——因此我们可以select student_class。

第二列是一个count函数,上一次我们说过,count函数是一个聚合函数,他会统计本组内的个数——因此我们可以select count(1)

那如果我们再想select student_sex,可不可以呢?

尽管网页提示我们可以,但实际上在大多数数据库中,是不可以的。会提示你,student_sex 不再 group by字段中,无法select。

为什么?

因为数据仅仅按照student_class分组,那么在每组数据内,只能保证student_class字段相同的,不能保证student_sex是相同的。在这种情况下, MySQL不会允许select这个字段

如果你希望把它select出来,则需要确保每组的student_sex都相同——把student_sex加入group by字段

SELECT

`student_class` as '门派',

count(1) as '人数',

`student_sex`

FROM

`student_info`

GROUP BY

`student_class`,`student_sex`

ORDER BY

`人数` DESC

;

经过分组,会保证每组内的student_class,student_sex都相同,因此组的数量自然会增多,变成下面的样子:

分组的数目由5上升到了8

如果你在select的时候使用了一些函数,比如你希望数据以“木叶_男”(student_class + student_sex),那么你在group by 的时候可以把这两个字段分别group,或者合起来group,如下:

SELECT

concat(`student_class`, '_',`student_sex`) as '门派',

count(1) as '人数'

FROM

`student_info`

GROUP BY

`student_class`,`student_sex`

ORDER BY

`人数` DESC, `门派`

;

这里的concat()函数,是把括号里面的文字拼接起来

也可以把group by写作是:

SELECT

concat(`student_class`, '_',`student_sex`) as '门派',

count(1) as '人数'

FROM

`student_info`

GROUP BY

concat(`student_class`, '_',`student_sex`)

ORDER BY

`人数` DESC, `门派`

;

都是可以的。

只要你可以保证,每个组内被select出来的字段值都是一样的。

结果如下:

分组的概念就介绍到这里

如果你不是很懂,那么多练几次就好了。

2,列名

大家应该有注意到,我总是喜欢select 之后,给他们取一个别名,这个别名被单引号包围('门派' '人数'),但是在order by字段的时候,他被反引号包围(`门派` `人数`)。

因为他已经是列名了。

而在group by字段里,不能输入别名。

这是为什么呢?

其实这里涉及到MySQL执行顺序,当我们执行一条select语句时,会生成一张临时的结果表。这张表的列名,就是select时的名字。

group by是在表生成之前执行的,而order by是表生成之后执行的。

我们可以对这张结果表进行查询

子查询

先select 出来一张表,然后再这张表上面再做一次查询

你可以无限地嵌套下去

我们来看一个需求:

列出所有的,女性人数小于2的门派

这个需求可以分成2步做

我首先按照门派、性别分组,统计人数

然后过滤——性别是女性,人数小于2

SQL如下:

SELECT

*

FROM

(

SELECT

`student_class` as '门派',

`student_sex`,

count(1) as '人数'

FROM

`student_info`

GROUP BY

`student_class`, `student_sex`

ORDER BY

`人数` DESC, `门派`

) son_result

WHERE

son_result.`student_sex` = '女' and son_result.`人数` < 2

;

双层嵌套的子查询

来看这个SQL,它是2层的,首先看里面这层:

(

SELECT

`student_class` as '门派',

`student_sex`,

count(1) as '人数'

FROM

`student_info`

GROUP BY

`student_class`, `student_sex`

ORDER BY

`人数` DESC, `门派`

) son_result

这一段语句,将会生成一个子表格,叫做son_result,这个表格有3个字段

门派student_sex人数

数据库会先执行这一段SQL,把表格生成完毕,然后再来看外面的SQL,我把它简化成这个样子:

SELECT

*

FROM

son_result

WHERE

son_result.`student_sex` = '女' and son_result.`人数` < 2

;

这样是不是就很明了了?

最后的执行结果如下:

理论上。你可以根据子查询来写无限长的SQL,嵌套无限层子查询,你只需要关注最外面的那个子查询会生成什么样的表结构就行了——完全取决于你的select字段。

更多精彩内容详细了解百战程序员哦!另外喜欢文章请点击关注谢谢啦!小编会提供更多实用的干货给大家的!

标签: #mysql入门很简单 #mysql零基础