产品操作MySQL第5篇 – 数据查询-排重查询

MYSQL


本资料为产品岗位作为日常工作参考,语言口语化

At 2019/4/22 By David.Yang


排重查询(使用DISTINCT运算符来消除结果集中的重复行)

针对现有业务数据进行查询时,会有重复的数据记录,

有时候我们需要进行排重的数据查询,为了避免重复数据,

我们通常使用DISTINCT进行处理。


语法:

SELECT DISTINCT

    column[,column...]

FROM

    table_name

WHERE

where_conditions;


这个查询语法我们在看完SELECT语法后应该比较熟悉了。


其中column可以是多个字段哦~


DISTINCT语句演示

为了进行数据演示,我们将学生表加入国家字段,代表各个学生的国际都是哪些。


不知道大家是否还记得怎么对数据表进行字段新增的?

SQL

ALTER TABLE `students` ADD `nationality` varchar(20) COMMENT '国籍' AFTER `age`;


然后把数据补进去。


然后呢?


校长先生想看看今年的学生招收情况,这些学生都来自哪些国家?


我们教导主任周伯通,这可就难为了,

因为他知道,想要知道所有学生的国籍呢,

这个简单啊,他会,

只要这么做就行了


SQL

SELECT

nationality

FROM

students;

周伯通一看好开心呀~

看,学生来自五湖四海,大江南北啊,有南宋的,有西辽的,有西夏的,


看来俺们这学校声誉不错啊。


等等,咋是南宋、南宋一样一样的呢?


可是这不行啊,校长要的是生源地,怎么还有重复的呢?

这可愁坏了教导主任周伯通。


怎么才能去掉重复的呢?


这旁边一看坐的谁啊?

老情敌一灯大师啊!


没办法,校长的任务还得干,

没什么不好意思的,问吧


“额,那啥,一灯”

“当年是我不对啊,抢了你媳妇儿瑛姑”

“你都当和尚了,也就不计较了,咱进行个学术讨论啊”


“讷啥,你看看我这校长给的统计生源的事儿,你给瞅一眼呗”


一灯答:“行”


“看老衲给你点拨一二”


一灯的SQL是这么写的


SQL

SELECT DISTINCT

       nationality

FROM

       students;


一灯“牛逼不,就一字儿”


“嗯… 嗯~”


以上,就说明了DISTINCT关键字是干什么的了,他成功的消除了重复项。


DISTINCT多列怎么用

一灯曰“再给你开个光,瞅瞅多个列会有啥效果”

SQL

SELECT DISTINCT

nationality, gender

FROM

students;


结果集会告诉你南宋下的生源有男、女性别,

西夏就不同了,只有姑娘,没有男娃儿。


以上假如我们还有学生的县府数据,上边的示例变通一下,

我们是不是就可以获得国籍– 府县了呢?


比如:

SELECT DISTINCT

       nationality,州字段

FROM

       students;


南宋– 京兆府

南宋– 延安府

南宋– 商州

南宋– 同州

南宋– 华州


如果不是有DISTINCT语句控制,你得到的数据将会是

南宋– 京兆府

南宋– 京兆府

南宋– 京兆府

南宋– 延安府

南宋– 延安府

南宋– 延安府

南宋– 商州

南宋– 商州

南宋– 商州

南宋– 同州

南宋– 华州



DISTINCT对NULL值的处理

我们再招一个洋学生,叫路易11,不设置他的国籍,

数据库对应国籍为NULL,我们看看会是什么结果?

SQL

SELECT DISTINCT nationality FROM students;


DISTINCT对NULL类型数据是不进行过滤的,

即返回结果集中会包含NULL的值。


那我们要排除NULL的空数据呢?


可以直接在WHERE条件中加以限制。

SQL

SELECTDISTINCTROW

       nationality

FROM

       students

WHERE

       nationality IS NOT NULL;


注:后续过滤查询会讲解WHERE子句


DISTINCT对*值的处理

mysql> SELECT DISTINCT * FROM students;


这时候其实等价于:


SELECT DISTINCT

       nationality,gender, xxx, xxx, xxx, …

FROM

       students;


DISTINCT与LIMIT

我们前文提起过LIMIT,用来限制返回的数据记录条数,

这里也同样可以使用。


SQL

SELECT DISTINCTROW

nationality

FROM

students

LIMIT 3;

注:后续过滤查询会讲解LIMIT子句


DISTINCT与GROUP BY子句比较

GROUP BY看字面意思聚合,分组,我们大概就能想到,

他与DISTINCT多少有点关系,或能做差不多的事情,


你别说,还真是。


比如我们要用GROUP BY来实现生源地统计,该怎么做呢?

一灯大师会这么做:

SQL

SELECT 

nationality

FROM

students

GROUP BY

nationality;


一灯说“瞅见没,一样一样的”


“不对呀,不是一样一样的撒,这不顺序不太一样么?和尚”


确实,顺序是不一样。


一般来说,DISTINCT和GROUP

BY字句能干差不多的事,

那我们要是给DISTINCT加个排序呢?


(别慌,排序我们后文会讲的,现在留个印象日后好相处)


SQL

SELECT DISTINCT

       nationality

FROM

       students

ORDER BY

       nationality;


DISTINCT与聚合函数的组合使用

SQL当中有一些聚合函数,比如SUM/COUNT/AVG等等,

他们可以用来与DISTINCT组合使用进行一些业务场景的查询。


-- 统计班级性别的分布情况


SQL

SELECT

gender, COUNT(DISTINCT number)

FROM

students

GROUP BY

gender;


因为学号是学生的标记,我们通过DISTINCT就可以排除重复学号数据,

在通过COUNT进行计数统计,

后然通过gender进行分组;


再比如统计学生年龄分布,可以这么写:

SQL

SELECT

       age, COUNT(DISTINCT number)

FROM

       students

GROUP BY

       age;


注:

此种场景不能脱离GROUP BY字句。


-- 统计学生最大年龄,并统计有多少人?

SQL

SELECT

       max(age), COUNT(DISTINCT number)

FROM

       students

WHERE

       age = (SELECT max(age) FROM students);


当然你也可以加上条件进行查询,

比如看来自西夏的学生最大年龄是多少,有多少人?


SQL

SELECT

       nationality, max(age), COUNT(DISTINCTnumber)

FROM

       students

WHERE

       nationality = '西夏'

AND

       age = (SELECT max(age) FROM studentsWHERE nationality = '西夏');


SQL解释

ϒ 以上在WHERE当中使用了子查询,需要通过子查询先算出最大年龄是多少,再进行外围SQL的查询。

所以你如果这么写,就会报错

SQL ERROR

SELECT

max(age), COUNT(DISTINCT number)

FROM

students

WHERE

age = max(age);


错误提示:

为什么呢?


聚集函数也叫列函数,它们都是基于整列数据进行计算的,

而where子句则是对数据行进行过滤的(这里过滤是在一个记录里边过滤的,基于"行"),


在筛选过程中依赖“基于已经筛选完毕的数据得出的计算结果”是一种悖论,

这是行不通的。


更简单地说,因为聚集函数要对全列数据时行计算,


因而使用它的前提是:结果集已经确定!


而where子句还处于“确定”结果集的过程中,因而不能使用聚集函数。


ϒ 如果你需要再进一步限定WHERE条件,那么请再子查询和WHERE条件内进行条件的操作

比如前面例子,我只想统计来自西夏的学生,


那么你需要现统计出西夏学生的最大年龄,这个在子语句中实现,

这时候你已经得到了西夏的行数据中年龄列的最大值;


在外部WHERE查询时,时针对整体行进行查询,

所以他需要对条件【国籍=西夏】进行限定,使得过滤出【国籍=西夏】的数据。


WHERE和子语句组合使用使得你查询的数据保持正确性。


如果在子查询中使用了【国籍=西夏】的条件,

而WHERE并为进行条件过滤,那么你其实是在做这么一件事,


通过子语句得到一个最大值的年龄,比如16,

然后查询所有【国籍=所有】学生,年龄=16的学生,共有多少人。


SQL

SELECT

max(age), COUNT(DISTINCT number)

FROM

students

WHERE

age = (SELECT max(age) FROM students WHERE nationality = '西夏');


但其实西夏的最大年龄16岁,学生只有1个


正确结果



本篇章讲解了查询中消除重复行的相关语法,

到此你应该能够进行数据去重复业务上相关的数据操作。


Bye Bye.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,816评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,729评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,300评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,780评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,890评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,084评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,151评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,912评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,355评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,666评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,809评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,504评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,150评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,121评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,628评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,724评论 2 351

推荐阅读更多精彩内容