zoukankan      html  css  js  c++  java
  • 关于Django中的数据库操作API之distinct去重的一个误传

    转载自http://www.360doc.com/content/18/0731/18/58287567_774731201.shtml

    django提供的数据库操作API中的distinct()函数,了解SQL语句的读者都应该知道,DISTINCT关键字可以在select操作时去重。django里的这个distinct()函数也是这个功能,通常的用法是我们要取出一张表中的某一列的所有值,并且只取出不重复的,如果有重复的就只取出来一次,网络上几乎所有的对这个函数的使用例子对应的Python代码都如下:

     但是这样的用法往往达不到使用者的意图,可以来看一下网络上流传甚广的一个问答:
    比如这个:http://bbs.csdn.net/topics/330006477
    再比如这个:http://www.douban.com/group/topic/17856879/
    这里其实说的都是一个例子,仔细看这个解答

    —–
    需要注意的是,这样返回的是一个字典的列表,而不是通常的 QuerySet
    —
    这样是过滤不掉的,这是个问题,还是有5个对象在里面,对结果使用len(obj)就知道没有任何变化,但是如果只作统计不重复数据的个数的话,还是准确的3个
    obj=ClassName.objects.values(‘name’).distinct()
    len(obj)=5
    obj.count()=3
    但是结果集中没有起到任何的过滤作用,此问题有待解决!!!!!

    有理有据,让人很信服的认为distinct()函数没有实现其所描述的功能。真的是这样么?

    在这里负责的告诉读者,上面的解释是错误的,distinct()具有去重功能是没有必要怀疑的,那为什么会出现上面的解释呢?因为他不知道distinct()函数有一个隐藏特性,当使用distinct()函数的时候,如果不使用order_by()函数做跟随,那么该函数会自动把当前表中的默认排序字段作为DISTINCT的一个列,所以上述问题出现的原因是因为他没有使用order_by(‘name’)来屏蔽distinct()的那个特性,从而得出的distinct结果并不是仅仅以name一个列作为参数的,而是以id+name两列的值作为distinct参数,可以看到id列里面的值全部都是唯一值,所以得出来的结果必然是以id列的值为标准的,这也就是的原因,而如果想要实现上述例子中楼主的需求,正确的代码写法是:

    Python

    d1 = models.Device.objects.values('business_id').distinct().order_by('business_id')

    在1.4+版本的django中distinct()函数可以传入一个参数,从而省去了后面跟加一个order_by()函数的必要,但是这也需要你的数据库支持Postgresql,否则还是无效的。

  • 相关阅读:
    链表_单链表(插入删除查询)
    OceanBase架构浅析(一)
    电商商品搜索现状
    ASP.NET MVC 源码分析(二) —— 从 IRouteBuilder认识路由构建
    ASP.NET MVC 源码分析(一)
    RPC框架分析
    RPC简介
    Performance Metrics(性能指标2)
    Performance Metrics(性能指标1)
    Introduction(本书简介)
  • 原文地址:https://www.cnblogs.com/jiangxiaobo/p/11646179.html
Copyright © 2011-2022 走看看