场景

有一张得分表(score),记录了用户每次的得分,同一个人可能有多个得分。

id name score
1 tom 45
2 jack 78
3 tom 34
. . .

需求:找出分数最高的前5个人。

SQL1

首先我们写个最简单的sql:

select
id, name, score
from
score
order by
score desc
limit 5;

如果sql这样写,结果可能是:

id name score
2 jack 78
1 tom 45
3 tom 34

排序了,但是没有去重

SQL2

那么我们加上去重:

select
distinct name
from
score
order by
score desc
limit 5;

首先第一点是这个sql未必能执行。在一些数据库版本,这个sql可以被执行,在一些版本则会提示你order by的字段必须在distinct中存在(见SQL3)。

但是即使能执行,这个sql也得不到预期结果。原因是distinct优先于order by 被数据库执行。

在执行distinct name的时候,如上文中的数据。是取id=1的数据,还是id=3的数据呢?其实这是数据库自行决定的。因此,可能会不正确选择数据。

比如真的执行这个sql,可能去重的结果是:

id name score
2 jack 78
3 tom 34

然后再执行一个order by,就会认为第一名是jack78分,第二名是tom34分。然而其实tom应该是45分,这个45分就在数据库执行distinct的时候被错误的丢弃了,毕竟先执行distinct的时候不知道你到底要哪个数据。

SQL3

那么我们把score加入select中呢?

select
distinct name, score
from
score
order by
score desc
limit 5;

很明显,这样写的执行结果和我们预期不符。因为如果写:distinct name,score实际上是对name和score一起去重。比如name都是jack,score都是45。那么这行就会被去掉。

但是问题是正因为把score当做去重的条件了。所以对于同名的人,比如都叫tom,会因为其有两个分数,导致不能被去重,从而保留两行记录。结果就是好像没有去重。

SQL4

那我不用distinct,用group by进行去重可以吗?

select
name
from
score
group by
name
order by
score desc
limit 5;

也不行,因为在group by的时候,数据库还是不知道对两行name一样的数据,究竟应该留下哪一行。

SQL5

正确的写法:

select
name
from
score
group by
name
order by
max(score) desc
limit 5;

这样写,在执行group by的时候,数据库就知道要保留score最大的那一行了。

sql如何先排序再去重的更多相关文章

  1. 不简单的SQL查询和排序语句

    真不简单!! 一:使用select语句进行查询 语法: SELECT    <列名> FROM      <表名> [WHERE    <查询条件表达式>] [OR ...

  2. mysql 怎样先排序再分组

    权游游牧族:众所周知!一句SqL语句不能先排序再分组.所以这里给出几个案例 --表结构-- create table `shop` ( `id` int (10) PRIMARY KEY, `shop ...

  3. SQL语句分组排序,多表关联排序

    SQL语句分组排序,多表关联排序总结几种常见的方法: 案例一: 在查询结果中按人数降序排列,若人数相同,则按课程号升序排列? 分析:单个表内的多个字段排序,一般可以直接用逗号分割实现. select ...

  4. 帝国CMS系统标签e:loop调用的附加SQL条件和排序参数

    帝国CMS6.5以上版本在原来所有信息调用标签基础上增加了两个标签参数:“附加SQL条件”和“显示排序”.支持这两个参数的标签有如下:ecmsinfo.灵动标签.phomenews.phomenews ...

  5. SQL SERVER 的排序规则

    有时候查询数据库的时候会发现(比如做重名检查的时候):数据库的查询时对大小写不敏感的,也就是 A 和 a 是一样的. 也就是说 select * from tabletest where name = ...

  6. SQL Server更改排序规则的实现过程

    摘自: http://www.2cto.com/database/201112/115138.html 以下的文章主要向大家描述的是SQL Server更改排序规则的实现过程,以及在实现其实际操作过程 ...

  7. Spring data JPA先排序再分页。

    //工具类,增删改查等等package com.yunqing.service.impl; import java.util.Map; import org.springframework.beans ...

  8. java对一个int数组进行排序、去重

    思路: 1.使用 HashSet 进行去重 2.将 HashSet 变为 TreeSet 3.使用 TreeSet 进行排序 4.将 Set 变为 Integer 数组 5.将 Integer 数组变 ...

  9. 页面上有3个输入框:分别为max,min,num;三个按钮:分别为生成,排序,去重;在输入框输入三个数字后,先点击生成按钮,生成一个数组长度为num,值为max到min之间的随机整数点击排序,对当前数组进行排序,点击去重,对当前数组进行去重。 每次点击之后使结果显示在控制台

    <!DOCTYPE html> <html> <head> <!-- 页面上有3个输入框:分别为max,min,num:三个按钮:分别为生成,排序,去重: 在 ...

随机推荐

  1. 添加fileinfo扩展

    首先声明:笔者用的是军哥的lnmp一键安装包!链接地址:https://lnmp.org 打开upgrade_php.sh配置文件[文件所在位置:~/lnmp1.4/include/upgrade_p ...

  2. jqGrid使用手册

    JQGrid是一个在jquery基础上做的一个表格控件,以ajax的方式和服务器端通信. JQGrid Demo 是一个在线的演示项目.在这里,可以知道jqgrid可以做什么事情.jQgrid 使用详 ...

  3. Java 使用Apache POI读取和写入Excel表格

    1,引入所用的包 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxm ...

  4. Spring常见面试题

    本文是通过收集网上各种面试指南题目及答案然后经过整理归纳而来,仅仅是为了方便以后回顾,无意冒犯各位原创作者. Spring框架 1. 什么是Spring? Spring 是个java企业级应用的开源开 ...

  5. C#中给WebClient添加代理Proxy

    效果图: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; ...

  6. Source Insight的使用

    1. source insight查看函数的上一级调用的位置(函数) --> 鼠标放在函数上,右键 选择 Jump To caller,就可以看到有哪些函数调用它了:

  7. ruby 数据类型String

    一.字符串创建 单引号包含,不支持转义符和内嵌表达式#{}(插值符) str = 'hello world!' 双引号包含 str = "hello world!" 使用%,%Q, ...

  8. Java学习笔记十一:Java中的方法

    Java中的方法 一:什么是方法: 所谓方法,就是用来解决一类问题的代码的有序组合,是一个功能模块. 学过C语言或者其他语言的应该都知道函数这个东西,在Java中,其实方法就是函数,只不过叫法不同,在 ...

  9. DHT11温湿度传感器编程思路以及代码的实现(转载)

    源自:https://blog.csdn.net/qq_34952376/article/details/81193938 在我们刚开始进入单片机的学习中,练习写传感器的时序是必不可少的,其实我比较推 ...

  10. go学习笔记-基础类型

    基础类型 布尔值 布尔值的类型为bool,值是true或false,默认为false. //示例代码 var isActive bool // 全局变量声明 var enabled, disabled ...