相信小伙伴们在后台开发过程中和数据库打交道经常需要排重,因此今天主要来记录一下和排重相关的几个关键字。
DISTINCT和GROUP BY,其实在一定情况下之前记录的TOP关键字也可以用来排重
DISTINCT
DISTINCT中文翻译为有区别的,在SQL语句中此关键字也只会返回有所不同的内容,把相同的内容过滤掉,因此起到排重的作用。基本语法为:
SELECT DISTINCT 列名称 FROM 表名称
DISTINCT依照 后面跟的列名称来排重,可以是一个字段,也可以是多个字段,并且只返回用来排重的这些字段,接下来就举例子来看什么情况下使用此排重方法。
首先我们来创建一张排重表
,并使用INSERT INTO 排重表(id,name,identityid,age) VALUES('4','小果冻','130423199401102534','26')
来插入几条数据,我们看最终的结果为:
现在有一个需求就是需要知道表中到底有几个身份证号号,可以发现
小明
和小红
的identityid
是相同的,接下里我们使用DISTINCT
关键字看是否可以得到理想的结果
SELECT DISTINCT identityid FROM 排重表
结果为:
从上面我们可以看到得到了排重之后的
identityid
,由此可见关键字DISTINCT
后面跟的列名称是用来排重的也是用来返回的。接下来我们看通过两个字段来排重,也就是说这两个字段均相同才算是重复
SELECT DISTINCT id,identityid FROM 排重表
结果为:
当然你也可以按除id外的所有字段来排重,但是需要注意的是DISTINCT后面跟的字段是排重字段也是最后输出结果的字段,而且此关键字必须放在SELECT后面,其他的前面,比如TOP等的前面.
接下来看一下和
COUNT
关键字共同使用的例子
//按一个字段排重后的count数
SELECT COUNT(DISTINCT age) FROM 排重表
//按多个字段排重的count数
SELECT COUNT (*)FROM(SELECT DISTINCT name,identityid,age FROM 排重表)AS b
运行结果大家可以自己试一下。
GROUP BY
GROUP BY分组统计,形式上也是用来排重,但是和上面的DISTINCT的使用场景不太一样,一般和聚合函数一起使用,像SUM,MAX,GROUP_CONCAT等,小心小伙伴们看到下面的例子就可以体会到和DISTINCT的区别。
首先我们先来新建一张表,来简单的记录一下班级中学生的数学成绩,通过下面的sql语句来批量的插入数据
//注意使用的关键字是VALUES而不是VALUE
INSERT INTO score(id,name,class,mathscore) VALUES('4','小糖豆','二班','79'),('5','小狗答','三班','93'),('6','小乌龟','三班','76')
接下来我们看到这张表中的数据是这样的:
那么我如果想知道各个班级的平均成绩怎么办呢?
SUM,COUNT
//解释一下这句sql,通过class进行分组后,计算SUM(mathscore)就会得到按照某个class计算的分数和,而COUNT(mathscore)则会得到某个class下几个mathscore,两者相除则是该班级成绩平均数,AS关键字之前已经记录过了,这就不重申了。
SELECT class,SUM(mathscore)/COUNT(mathscore) AS average FROM score GROUP BY class ORDER BY average DESC
补充:
COALESCE(SUM(mathscore),0),这句sql的意思是当和为null,时转变成0,一般在业务中使用到,从数据库中查到的数据时null时未做安全判断直接进行操作,会报空指针的错误,所以可以直接在sql层处理掉!
运行结果为:
那如果想要知道某个班的最高分数呢?
SELECT class,MAX(mathscore) AS maxscore FROM score GROUP BY class ORDER BY maxscore DESC
运行结果为:
注意:SELECT 后面跟的列名称必须是GROUP BY子句后面的分组对象或聚合函数,否则会报错。如SELECT * FROM score GROUP BY class,id,name;在这条sql中是按照class,id,name来进行分组的,但是SELECT * 表示查询该表中所有字段,但又因为mathscore不做分组标志,因此会报错
[Err] 42000 - [SQL Server]选择列表中的列 'score.mathscore' 无效,因为该列没有包含在聚合函数或 GROUP BY 子句中。
那么如果我们想要看各个班的成绩列表呢?
GROUP_CONCAT
SELECT class, GROUP_CONCAT(name,mathscore),GROUP_CONCAT(mathscore) FROM score GROUP BY class