Django原始查询:使用GROUP BY的计数查询

6 投票
1 回答
3602 浏览
提问于 2025-04-18 09:49

出于某种原因,我需要使用原始的SQL查询,并通过mymodel.objects.raw(query)来执行它。但是我发现主键总是需要传递。这让我在做一些查询时遇到了困难。

想象一下一个简单的查询,我在一个表上做count(*),并对两个列进行条件检查:

select count(*), column_value from tableX where column_label = 'Age' group by column_value having column_value > 30;

在pgsql中,这样的查询可以正常工作,并返回类似这样的结果:

 count | column_value 
-------+----------------
     1 |       38.00000
     2 |       45.00000
     1 |       35.00000
     1 |       44.00000

注意第二行。这正是我想要的结果。但是在django中,我必须传递主键,因此我需要把查询改成:

假设'id'是主键:

    select count(*), id, column_value from tableX where column_label = 'Age' group by column_value, id having column_value > 30;

现在,这样的查询会给我类似这样的结果:

 count |  id  | column_value 
-------+------+----------------
     1 | 4041 |       45.00000
     1 | 3876 |       38.00000
     1 | 3821 |       45.00000
     1 | 3931 |       35.00000
     1 | 3986 |       44.00000
(5 rows)

如果我运行聚合命令后仍然看到所有单独的行,这对我来说没有任何用处。有没有其他方法可以仅使用原始查询在django中获得上面提到的第一个结果?有没有什么方法可以绕过主键的限制?

1 个回答

9

一个可能的解决办法是直接使用 connection.cursor(),然后执行原始的查询语句:

from django.db import connection

cursor = connection.cursor()
cursor.execute("""select 
                      count(*), column_value 
                  from 
                      tableX 
                  where 
                      column_label = 'Age' 
                  group by 
                      column_value 
                  having 
                      column_value > 30""")
result = cursor.fetchall()

撰写回答