问题描述

因为要设计一个数据库表,进行一个倒序去重的操作。

例如:

id

Name

1

B

2

A

3

A

4

C

5

C

6

B

场景:例如说我们需要得到一个用户的搜索记录,那么肯定不会仅仅根据时间倒序排序给出列表展示,因为这样会出现重复的问题。我们需要去重,并且保证用户对一个搜索记录是按照最后一次搜索操作的时间排序的。

用以上用例去描述,id为添加顺序,Name为查询记录,我们需要Sql查询的结果为BCA。

一开始选择使用了DISTINCT方式。然而实践过程中,DISTINCT方案是行不通的。

原因

我们是不是会认为这个仅仅是需要DISTINCT Name去重加上ORDER BY id DESC 就解决了呢?

SELECT DISTINCT(Name) from table Order by id DESC 

首先,这样做是没有意义的。因为DISTINCT操作会先于Order by 操作,id的列已经不见了,Order by 只能指定显示列名。况且已经进行了DISTINCT去重操作了,Name与id不是唯一对应关系,排序当然也无从谈起了。(这样写在不同的机器上据说表现情况不一样,有些会直接报错,我的没有)

附上一下Mysql语句执行顺序

(7)     SELECT
(8) DISTINCT <select_list>
(1) FROM <left_table>
(3) <join_type> JOIN <right_table>
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) HAVING <having_condition>
(9) ORDER BY <order_by_condition>
(10) LIMIT <limit_number>
 

那么可不可以先排序出子表,再用DISTINCT去重呢?

SELECT DISTINCT(Name) from (Select * from table Order by id DESC)tb1 
 

实验结果不满足要求,并且结果很奇怪,是一个莫名其妙的顺序(顺序既不是正序,也不是倒序,也不是降序,加了limit结果又会不一样)。

这条语句能否成功的关键点,就在于DINSTINCT的顺序是否与原表的顺序有关。

在查看了很多文章后,我都没有看到对这个知识点的描述。但是最后我翻到了一些其他的东西。

有一位使用Sql server的先生这样写

实事求是的讲,就现在我遇到的情况,如果distinct 不写order by 的话,实际结果集的输出顺序依赖于两个条件。
​
1、生成的查询计划的顺序(在不同版本的sql server 解释同一个语句的执行计划会有所不同,统计信息不同也会有所不同)
​
2、数据存储和访问的顺序 (这个要看是否有索引等) 还是需要具体情况,具体分析的。
​
个人愚见,参考
 

还有一位先生这样写

没有order by子句的所有查询都不保证顺序,即使有聚集索引
​
因为优化器可能会选择并行处理,或者在多文件情况下不按“期待”顺序扫描数据,所以无法保证数据的顺序。唯一能确保顺序的只有order by。
distinct内置是需要排序然后去重的,但是最终结果可能又会乱掉。另外根据sqlserver排序规则,不同的排序规则也有不同的结果

我还看到了Mysql的使用者也提出过,同样的Mysql,同样的sql语句,得出的查询结果出现了顺序不同的问题。

最后我觉得可以初步得出这个结论:虽然没有得出Mysql究竟是以怎样的算法进行的排序,怎样的算法实现DISTINCT操作(考虑到各版本,各引擎实现方法可能还不同,这个工作量可能非常的大),但是因为出现了无序的情况,就可以说任何没有Order By子句的查询都不能保证顺序,所以这个需求,以DISTINCT语句不能实现。

DISTINCT一般用来:1.去重拿结果。2.统计数目。其他的需求暂时就不要考虑这个了,Group by比较好用,一般效率也不差DISTINCT,甚至会更高。

实现该需求应该用Group by。

 

Select Name from table group by Name order by max(id) desc 

但是这样会出现有一个无法用到id索引的问题,最后没有办法,只能改变表结构去实现了,如果拥有可以不用改变表结构就能实现并且能完全走索引的方法的同学,欢迎指导,我请你喝肥宅快乐水。

Mysql DISTINCT问题的更多相关文章

  1. mysql distinct跟group by性能

    mysql distinct和group by性能   1,测试前的准备 //准备一张测试表 mysql> CREATE TABLE `test_test` ( ->   `id` int ...

  2. mysql distinct、group_concat

    mysql distinct语句用于查询多条不重复记录值(去重.过滤多余的重复记录) distinct同时作用了两个字段或者两个以上的字段,必须得作用了的字段都相同的才被排除.如果想让单个列" ...

  3. mysql distinct field1,field2,field3, .... from table

    mysql distinct field1,field2,field3, .... from table 我们知道 这样的sql可以去掉重复项 (field1的重复项); select distinc ...

  4. mysql DISTINCT语句 语法

    mysql DISTINCT语句 语法 作用:用于返回唯一不同的值. 语法:SELECT DISTINCT 列名称 FROM 表名称.扬州大理石量具 mysql DISTINCT语句 示例 //从表中 ...

  5. mysql distinct

    mysql的DISTINCT的关键字有很多你想不到的用处1.在count 不重复的记录的时候能用到比如SELECT COUNT( DISTINCT id ) FROM tablename;就是计算ta ...

  6. mysql distinct&group by 应用

    在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供 有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数,而不是用它来返回不重记录的 ...

  7. MYSQL DISTINCT Optimization

    在很多情况下,Distinct和order by的组合需要建立一个内存临时表.  因为distinct关键字可能利用group by,所以了解下mysql如何处理group by有帮助. distin ...

  8. mysql DISTINCT 的实现与优化

    DISTINCT实际上和GROUP BY的操作非常相似,只不过是在GROUP BY之后的每组中只取出一条记录而已.所以,DISTINCT的实现和GROUP BY的实现也基本差不多,没有太大的区别.同样 ...

  9. mysql distinct()用法

    在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数,而不是用它来返回不重记录的所 ...

  10. mysql distinct 用法详解及优化

    本事例实验用表task,结构如下 MySQL> desc task; +-------------+------------+------+-----+-------------------+- ...

随机推荐

  1. 【转】Android UI开发第三十一篇——Android的Holo Theme

    好长时间没写Android UI方面的文章了,今天就闲扯一下Android的Holo主题.一直做android开发的可能都知道,Android 系统的UI有过两次大的变化,一次是android 3.0 ...

  2. Ghostbusters(并查集,最小生成树)

    Ghostbusters 时间限制: 1 Sec  内存限制: 128 MB提交: 33  解决: 7[提交] [状态] [讨论版] [命题人:admin] 题目描述 The Bureau of Ap ...

  3. Makefile 简述

    定义 Linux 环境下的程序员如果不会使用GNU make来构建和管理自己的工程,应该不能算是一个合格的专业程序员,至少不能称得上是 Unix程序员.在 Linux(unix )环境下使用GNU 的 ...

  4. Spring3声明式事务处理事务无法回滚rollback分析(annotation与xml配置混用)

    新项目试运行,DBA提示生产数据库一个表的事务20分钟都未提交,分析过程如下: 1.查看日志log文件,最近20分钟是否有error日志: 2.发现某表有insert错误日志,初步判断由该表插入异常, ...

  5. 配置伪静态(URL重写)

    本篇借鉴了很多文章,这里做个记录. 有时我们的导航栏出现xx.aspx?id=x&name=xx 等等这样,会显得不好看,我们可以利用伪静态来美化我们的导航栏,伪静态的形式可以自己定义,本质还 ...

  6. js动画效果

    js能够按照预定的时间间隔重复调用一个函数,而这意味着我们可以随着时间的推移而不断改变某个元素的样式.动画是样式随时间变化的完美例子之一. js函数setTimeout能够让某个函数在经过一段预定的时 ...

  7. js加减乘除精确计算

    Javascript精确计算时的bug JS无法进行精确计算的bug 在做CRM,二代审核需求审核详情页面时.需要按比例(后端传类似0.8的小数)把用户输入的数字显示在不同的地方. 在做dubheIn ...

  8. Dijkstra&&Floyd

    文章来源:(http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html) (以下内容皆为转载) Dijkstra算法 1.定义 ...

  9. 【经典问题】bzoj2957: 楼房重建

    经典问题:动态维护上升子序列长度 进阶问题:[经典问题]#176. 栈 Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无 ...

  10. 如何在RedHat 7.0系统中安装mysql 5.7.22

    如何在RedHat 7.0系统中安装mysql 5.7.22 今天给大家介绍一下如何安装mysql5.7,在安装之前,首先要查看的是,你的系统中有没有已经安装过的情况.键入rpm -qa|grep m ...