【问题标题】:How to select columns without put a non-aggragate column in group by clause如何选择列而不在分组子句中放置非聚合列
【发布时间】:2013-07-29 18:05:52
【问题描述】:

我想知道如何选择列而不将它们放在 group by 子句中 例如:

select id, name, count(score) from users
group by name
order by count(score) desc

这里我不想按 ID 列分组

有人吗?

提示:Django 不允许我使用 min、max、avg、top,我需要强制选择没有函数的 ID。

【问题讨论】:

  • 哪个 RDBMS? MySQL似乎支持选择不在GROUP BY中的列。
  • 能否提供样本数据和预期结果?
  • 从select语句中去掉id列……这里没有意义。

标签: python sql django model group-by


【解决方案1】:

来自MySQL documentation

在标准 SQL 中,包含 GROUP BY 子句的查询不能引用选择列表中未在 GROUP BY 子句中命名的非聚合列。

这意味着在单个查询中实现您想要的唯一方法是使用OUTER JOIN 语句。据我所知,Django ORM 不支持从表到自身的 OUTER JOIN 语句。

除了使用原始 SQL 语句之外,获得所需内容的唯一方法是使用 2 个单独的查询和在 Python 中处理它们。

不过,我确实想知道,如果您不是要使用 SUM 而不是 COUNTCOUNT 为每个NON-NULL 值加1,包括0,而SUM 在列中添加实际数值。

无论如何,一个例子应该是这样的:

qs = Foo.objects.values('name').annotate(count=Count('id')) # or sum=Sum('score')
count = dict((x['name'], x['count']) for x in qs)
object_list = Foo.objects.all()
for foo in object_list:
    foo.count = count['name']

【讨论】:

    【解决方案2】:

    尝试使用聚合函数(例如min)为组选择一个id。

    select min(id) as id, name, count(score) as cnt 
    from users
    group by name
    order by count(score) desc
    

    您也可以改用max 函数。

    第二个解决方案:

    select u.id, u.name, 
    (select count(u1.score) from users u1 where u1.name = u.name ) as cnt
    from users u
    

    【讨论】:

    • 我不能使用 min 和 max 以及任何东西,django 不允许我使用它。
    • 你需要id栏吗?
    • 是的,因为django强迫我用这个栏目搜索模型。
    • 好的,所以如果你有 3 行名称为 John,我们将分组到一行,你想显示哪个 id?你可以试试第二个解决方案吗?
    【解决方案3】:

    任何未对其执行计算的列都需要包含在 GROUP BY 中。 为什么要在 SELECT 中而不是在 GROUP BY 中?

    【讨论】:

    • 因为如果我开始按 ID 分组,我的计数将毫无用处
    • 在这种情况下 - 为什么要在结果中包含 ID 列?
    • 因为 django 强制我将 ID 作为搜索模型的主键。
    猜你喜欢
    • 2016-09-14
    • 1970-01-01
    • 1970-01-01
    • 2020-04-28
    • 2016-11-19
    • 2013-07-27
    • 2018-08-09
    • 2018-07-31
    • 2015-08-03
    相关资源
    最近更新 更多