【问题标题】:Merging rows when counting - Django/SQL计数时合并行 - Django/SQL
【发布时间】:2011-06-19 10:57:54
【问题描述】:

我有以下型号:

class Item(models.Model):

    unique_code = models.CharField(max_length=100)
    category_code = models.CharField(max_length=100)
    label = models.CharField(max_length=100)

我想得到:

  • 使用的不同category_codes的计数

  • 使用的不同 unique_codes 的计数

  • 使用的不同 category_code 和 unique_code 组合的计数


有什么想法吗?

【问题讨论】:

    标签: python sql django postgresql django-models


    【解决方案1】:

    根据要求提供 Django/SQL 解决方案:

    使用的不同 category_codes 的计数:

    category_codes_cnt = Item.objects.values('category_codes').distinct().count()
    

    使用的不同 unique_codes 的计数:

    unique_codes_cnt = Item.objects.values('unique_codes').distinct().count()
    

    使用的不同category_code和unique_code组合的计数:

    codes_cnt = Item.objects.values('category_codes', 'unique_codes').distinct().count()
    

    【讨论】:

      【解决方案2】:

      不要浪费太多时间来尝试一个很酷的 SQL 解决方案。

      from collections import defaultdict
      count_cat_code = defaultdict(int)
      count_unique_code = defaultdict(int)
      count_combo_code = defaultdict(int)
      for obj in Item.objects.all():
          count_cat_code[obj.category_code] += 1
          count_unique_code[obj.unique_code] += 1
          count_combo_code[obj.category_code,obj.unique_code] += 1
      

      这样就可以了。而且它会相当快地工作。实际上,如果您进行一些基准测试,您可能会发现——有时——它与“纯 SQL”语句一样快。

      [为什么?因为 RDBMS 必须使用相当低效的算法来进行 GROUP BY 和计数。在 Python 中,我们可以奢侈地根据我们的应用程序假设一些事情,并且 我们对数据的了解。例如,在这种情况下,我假设它都适合 在记忆中。 RDBMS 内部算法无法做出的假设。]

      【讨论】:

      • @S.Lott:谢谢!! :) 但是如果它包含 100 万行怎么办,这里就是这种情况。有什么建议吗?
      • 没关系。在这方面,SQL 并不比 Python 快多少。无论如何都必须读取所有百万行。 SQL 通常必须先将它们分类到临时存储中,然后才能执行 GROUP BY,从而导致 O ( n log(n) ) 类型的性能。在 Python 中,您可以快速通过数据收集所需的一切。你的哈希表都是 O (1) 所以它是净 O (n)。
      • otoh,这确实意味着必须对每一行进行编组/传输/解组,这可能会比散列产生更多开销。不要猜测,测量。至少对于我使用的一个小例子,postgresql 无论如何都会做一个哈希聚合。
      • @araqnid:“确实意味着每一行都必须编组/传输/解组”。是的。 “这可能比散列的开销更大。”?什么?数据库无法为您进行哈希处理。 SQL 中的 GROUP BY 可能不涉及任何散列。 SQL 中的 GROUP BY 通常涉及巨大且昂贵的排序。表扫描可以更快。
      • 这将比在数据库程序中计算总数并将结果传输到客户端的 SQL 查询慢得多,尤其是在对象很大且很丰富的情况下。
      【解决方案3】:
      select count(distinct unique_code) as unique_code_count,
             count(distinct category_code) as category_code_count,
             count(*) as combination_count
      from (select unique_code, category_code, count(*) as combination_count
            from item
            group by unique_code, category_code) combination
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-09-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-14
        • 2013-01-12
        • 2015-01-29
        • 1970-01-01
        相关资源
        最近更新 更多