如何选择列而不在group by子句中放置非聚合列

时间:2013-07-29 19:36:05

标签: python sql django model group-by

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

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

此处我不想按ID列分组

有人?

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

3 个答案:

答案 0 :(得分:1)

来自MySQL documentation

  

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

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

除了使用原始SQL语句之外,获取所需内容的唯一方法(所有模型的列表,包括ID,每个唯一名称的出现次数),是使用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']

答案 1 :(得分:0)

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

答案 2 :(得分:0)

尝试使用聚合函数(例如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