2010-04-23 117 views
0

我在使用最新的sqlserver_ado庫的SQL Server 2005數據庫上使用Django 1.1.1。Django聚合查詢生成SQL錯誤

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') 

然後我想要做的彙總查詢到得到這些東西的前20個的平均ThingMonthValue在一段時間內,並且相同的值爲最後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') 

任何想法,爲什麼它的工作原理爲物聯網的一個切片,而不是第二個?我已經檢查過,並且兩個切片確實包含所需的東西。

回答

2

這看起來像Django ORM的SQL生成器中的錯誤。當不需要時,生成的SQL將返回_row_num以及第二個查詢的IN子查詢中的id

這不會需要爲前20計算,因爲子查詢可以寫成SELECT TOP 20...

爲了解決這個問題,去年ň行的計算,你可以返回的Things未收集彙總並用代碼進行平均計算。

(有可能是另一個Django的具體的解決方案,但我是一個SQL服務器的傢伙。)

+0

這基本上是我做了什麼,它是醜陋的,但工程。我已經用sqlserver_ado維護者提出了一張票據,希望他們能夠解決這個問題。謝謝! – meepmeep 2010-04-23 14:07:01