Форум сайта python.su
Всем привет! Стоит у меня следующая задача. Есть таблица:
from django.db import models
class AllElements (models.Model):
elem_name = models.CharField (max_length=25)
elem_value = models.IntegerField()
Офлайн
По идее так:
from django.db.models import Max
result = AllElements.objects.all().aggregate(Max('elem_value'))
Отредактировано (Ноя. 1, 2010 22:20:33)
Офлайн
regallТак я получу просто максимальное значение elem_value, а мне нужно при этом еще сделать группировку по elem_name и получить максимальное значение elem_value для каждого elem_name. Вот, как этот запрос выглядит на зыке SQL (Oracle):
По идее так:from django.db.models import Max
result = AllElements.objects.all().aggregate(Max('elem_value'))
select elem_name, max(elem_value) m_elemv from table_name
group by elem_name order by m_elemv
Отредактировано (Ноя. 2, 2010 14:04:21)
Офлайн
Попробуйте так
AllElements.objects.values('elem_name').annotate(max_elem_value=Max('elem_value'))
Офлайн
svasТут запрос будет проводить группировку по паре elem_name и elem_value, следовательно я получу одинаковые elem_name, если у них будут разные elem_value
Попробуйте такAllElements.objects.values('elem_name').annotate(max_elem_value=Max('elem_value'))
Офлайн
по моему я вас огорчу. была та же задача.
http://stackoverflow.com/questions/3508818/django-how-do-i-explicitly-make-a-query-with-a-having-clause
алсо сделал rawsql
Офлайн
Ordinarily, annotations are generated on a per-object basis - an annotated QuerySet will return one result for each object in the original QuerySet. However, when a values() clause is used to constrain the columns that are returned in the result set, the method for evaluating annotations is slightly different. Instead of returning an annotated result for each result in the original QuerySet, the original results are grouped according to the unique combinations of the fields specified in the values() clause. An annotation is then provided for each unique group; the annotation is computed over all members of the group.Не знаю почему вы решили что будет проводится группировка по паре. Сам не пробовал, но судя по документации должно работать.
Офлайн
svasЯ попробовал - вернуло все уникальные значения по паре и проверил запрос - он был на уникальность пары :(Ordinarily, annotations are generated on a per-object basis - an annotated QuerySet will return one result for each object in the original QuerySet. However, when a values() clause is used to constrain the columns that are returned in the result set, the method for evaluating annotations is slightly different. Instead of returning an annotated result for each result in the original QuerySet, the original results are grouped according to the unique combinations of the fields specified in the values() clause. An annotation is then provided for each unique group; the annotation is computed over all members of the group.Не знаю почему вы решили что будет проводится группировка по паре. Сам не пробовал, но судя по документации должно работать.
razum2umСпасибо за ссылку, видать, тоже прийдется raw-sql. Хотя, там стоит немного другая задача, если я првильно понял тот запрос.
по моему я вас огорчу. была та же задача.
http://stackoverflow.com/questions/3508 … ing-clause
алсо сделал rawsql
Отредактировано (Ноя. 5, 2010 22:11:36)
Офлайн
class AllElements(models.Model):
elem_name = models.CharField(max_length=25)
elem_value = models.IntegerField()
def __unicode__(self):
return u'%s, %s' % (self.elem_name, self.elem_value)
>>> from django.db.models import Max
>>> e = AllElements(elem_name = 'qwe', elem_value=1)
>>> e.save()
>>> e = AllElements(elem_name = 'qwe', elem_value=2)
>>> e.save()
>>> e = AllElements(elem_name = 'qwe', elem_value=3)
>>> e.save()
>>> e = AllElements(elem_name = 'asd', elem_value=4)
>>> e.save()
>>> e = AllElements(elem_name = 'asd', elem_value=5)
>>> e.save()
>>> e = AllElements(elem_name = 'qwe', elem_value=3)
>>> e.save()
>>> AllElements.objects.all()
[<AllElements: qwe, 1>, <AllElements: qwe, 2>, <AllElements: qwe, 3>, <AllElements: asd, 4>, <AllElements: asd, 5>, <AllElements: qwe, 3>]
>>> AllElements.objects.all().values('elem_name').annotate(max_elem_value = Max('elem_value'))
[{'max_elem_value': 5, 'elem_name': u'asd'}, {'max_elem_value': 3, 'elem_name': u'qwe'}]
>>>
Отредактировано (Ноя. 7, 2010 12:54:04)
Офлайн
svasПрошу прощения, я невнимательно применил у себя ваш пример и потому получил на выходе неверный запрос. Ваш ответ как раз то, что нужно. Спасибо большое!class AllElements(models.Model):
elem_name = models.CharField(max_length=25)
elem_value = models.IntegerField()
def __unicode__(self):
return u'%s, %s' % (self.elem_name, self.elem_value)Может я не понимаю что вам действительно нужно?>>> from django.db.models import Max
>>> e = AllElements(elem_name = 'qwe', elem_value=1)
>>> e.save()
>>> e = AllElements(elem_name = 'qwe', elem_value=2)
>>> e.save()
>>> e = AllElements(elem_name = 'qwe', elem_value=3)
>>> e.save()
>>> e = AllElements(elem_name = 'asd', elem_value=4)
>>> e.save()
>>> e = AllElements(elem_name = 'asd', elem_value=5)
>>> e.save()
>>> e = AllElements(elem_name = 'qwe', elem_value=3)
>>> e.save()
>>> AllElements.objects.all()
[<AllElements: qwe, 1>, <AllElements: qwe, 2>, <AllElements: qwe, 3>, <AllElements: asd, 4>, <AllElements: asd, 5>, <AllElements: qwe, 3>]
>>> AllElements.objects.all().values('elem_name').annotate(max_elem_value = Max('elem_value'))
[{'max_elem_value': 5, 'elem_name': u'asd'}, {'max_elem_value': 3, 'elem_name': u'qwe'}]
>>>
class AllElements(models.Model):
elem_name = models.CharField(max_length=25)
elem_value = models.IntegerField()
elem_other = model.CharField (max_length=25, unique=True)
def __unicode__(self):
return u'%s, %s' % (self.elem_name, self.elem_value)
class Meta:
ordering = ['elem_other']
AllElements.objects.all().values('elem_name').annotate(max_elem_value = Max('elem_value')).order_by('elem_name')
Отредактировано (Ноя. 10, 2010 23:07:59)
Офлайн