Я использую Django 1.1.1 на базе данных SQL Server 2005 с использованием новейшей библиотеки sqlserver_ado.
models.py включает в себя:
class Project(models.Model):
name = models.CharField(max_length=50)
class Thing(models.Model):
project = models.ForeignKey(Project)
reference = models.CharField(max_length=50)
class ThingMonth(models.Model):
thing = models.ForeignKey(Thing)
timestamp = models.DateTimeField()
ThingMonthValue = models.FloatField()
class Meta:
db_table = u'ThingMonthSummary'
В представлении я получил набор запросов, называемый «вещи», который содержит 25 вещей:
things = Thing.objects.select_related().filter(project=1).order_by('reference')
Затем я хочу сделать агрегированный запрос, чтобы получить среднее значение ThingMonthValue для первых 20 из этих вещей за определенный период и то же значение для последних 5.
Для первых 20 я делаю:
averageThingMonthValue = ThingMonth.objects.filter(thing__in=things[:20],timestamp__range="2009-01-01 00:00","2010-03-00:00")).aggregate(Avg('ThingMonthValue'))['ThingMonthValue__avg']
Это отлично работает и возвращает желаемое значение.
За последние 5 я делаю:
averageThingMonthValue = ThingMonth.objects.filter(thing__in=things[20:],timestamp__range="2009-01-01 00:00","2010-03-00:00")).aggregate(Avg('ThingMonthValue'))['ThingMonthValue__avg']
Но для этого я получаю ошибку SQL: «В списке выбора можно указать только одно выражение, если подзапрос не введен с EXISTS.»
SQL-запрос, используемый django, читает:
SELECT AVG([ThingMonthSummary].[ThingMonthValue]) AS [ThingMonthValue__avg]
FROM [ThingMonthSummary]
WHERE ([ThingMonthSummary].[thing_id] IN
(SELECT _row_num, [id] FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY [AAAA].[id] ASC) as _row_num,
[AAAA].[id] FROM ( SELECT U0.[id] FROM [Thing] U0 WHERE U0.[project_id] = 1 ) AS [AAAA]) as QQQ
where 20 < _row_num) AND [ThingMonthSummary].[timestamp] BETWEEN '01/01/09 00:00:00' and '03/01/10 00:00:00')
Есть идеи, почему это работает для одного кусочка вещей, а не для второго? Я проверил, и два ломтика правильно содержат нужные вещи.