zoukankan      html  css  js  c++  java
  • sql distinct详解以及优化

    一.distinct简介

    distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用 它来返回不重复记录的条数,而不是用它来返回不重记录的所有值。其原因是distinct只有用二重循环查询来解决,而这样对于一个数据量非常大的站来说,无疑是会直接影响到效率的。

    下面先来看看例子:

    table表

    字段1     字段2
       id        name
       1           a
       2           b
       3           c
       4           c
       5           b

    库结构大概这样,这只是一个简单的例子,实际情况会复杂得多。

    比如我想用一条语句查询得到name不重复的所有数据,那就必须使用distinct去掉多余的重复记录。

    select distinct name from table
    得到的结果是:

     ----------

    name
       a
       b
       c

    好像达到效果了,可是,我想要得到的是id值呢?改一下查询语句吧:

    select distinct name, id from table

    结果会是:

    ----------

    id name
       1 a
       2 b
       3 c
       4 c
       5 b

    distinct怎么没起作用?作用是起了的,不过他同时作用了两个字段,也就是必须得id与name都相同的才会被排除。。。。。。。

    我们再改改查询语句:

    select id, distinct name from table

    很遗憾,除了错误信息你什么也得不到,distinct必须放在开头。难到不能把distinct放到where条件里?能,照样报错。

    下面方法可行:

    select *, count(distinct name) from table group by name

    结果:

       id name count(distinct name)
       1 a 1
       2 b 1
       3 c 1

    最后一项是多余的,不用管就行了,目的达到。。。。。

    group by 必须放在 order by 和 limit之前,不然会报错

    ==============以上是关于Oracle的distinct的一种用法==============

    用distinct关键字只能过滤查询字段中所有记录相同的(记录集相同),而如果要指定一个字段却没有效果,另外distinct关键字会排序,效率很低。

    select distinct name from t1 能消除重复记录,但只能取一个字段,现在要同时取id,name这2个字段的值。
    select distinct id,name from t1 可以取多个字段,但只能消除这2个字段值全部相同的记录
    所以用distinct达不到想要的效果,用group by   可以解决这个问题。 

    二. distinct使用

    1  Distinct 位置

      单独的distinct只能放在开头,否则报错,语法错误

    mysql> Select  player_id,distinct(task_id) from task;

    ERROR 1064 (42000): You havean error in your SQL syntax; check the manual that

    corresponds to your MySQLserver version for the right syntax to use near 'disti

    nct(task_id) from task' atline 1

    现在把distinct放在开头

    mysql> Select  distinct(task_id),taskid from task;

    查询成功

    与其他函数使用时候,没有位置限制如下

      Select player_id,count(distinct(task_id))from task;

    这种情况下是正确的,可以使用。

    2  Distinct用法

    a.在count计算不重复的记录的时候能用到
    比如SELECT COUNT( DISTINCT player_id ) FROM task;
    就是计算talbebname表中id不同的记录有多少条

    b,在需要返回记录不同的id的具体值的时候可以用
    比如SELECT DISTINCT player_id FROM task;
    返回talbebname表中不同的id的具体的值

    c.上面的情况2对于需要返回mysql表中2列以上的结果时会有歧义
    比如SELECT DISTINCT player_id, task_id FROM task;
    实际上返回的是player_id与task_id同时不相同的结果,也就是DISTINCT同时作用了两个字段,必须得player_id与task_id都相同的才被排除了,与我们期望的结果不一样,我们期望的是player_id不同被过滤

      在这种情况下,distinct同时作用了两个字段,player_id,task_id

    d.这时候可以考虑使用group_concat函数来进行排除,不过这个mysql函数是在mysql4.1以上才支持的

    e. 其实还有另外一种解决方式,就是使用
    SELECT player_id, task_id, count(DISTINCT player_id) FROM task.
    虽然这样的返回结果多了一列无用的count数据(有时也许就需要这个数据)

    f 同时我们还可以利用下面的方式解决b遇到的歧义问题通过group by 分组

      select player_id,task_id from task group by player_id

  • 相关阅读:
    React生命周期, 兄弟组件之间通信
    React组件式编程Demo-用户的增删改查
    React之this.refs, 实现数据双向绑定
    CCF CSP 201812-4 数据中心
    CCF CSP 201812-4 数据中心
    PAT 顶级 1020 Delete At Most Two Characters (35 分)
    PAT 顶级 1020 Delete At Most Two Characters (35 分)
    Codeforces 1245C Constanze's Machine
    Codeforces 1245C Constanze's Machine
    CCF CSP 201712-4 行车路线
  • 原文地址:https://www.cnblogs.com/peijie-tech/p/3457777.html
Copyright © 2011-2022 走看看