Sql 对查询的输出应用稠密_RANK()

Sql 对查询的输出应用稠密_RANK(),sql,postgresql,dense-rank,Sql,Postgresql,Dense Rank,我有三个分别名为Groups、GroupMembers和DailyTable的表。以下是我为其中每一个设计的模型: 型号.py class Group(models.Model): name = models.CharField(max_length=255, blank=False, null=False) group_type = models.ForeignKey('GroupType',blank=True,default=False) class Meta:

我有三个分别名为Groups、GroupMembers和DailyTable的表。以下是我为其中每一个设计的模型:

型号.py

class Group(models.Model):

    name = models.CharField(max_length=255, blank=False, null=False)
    group_type = models.ForeignKey('GroupType',blank=True,default=False)

    class Meta:
        db_table = 'groups'

class GroupMembers(models.Model):
    group = models.ForeignKey('Group')
    user = models.ForeignKey('User')
    status = models.CharField(max_length=20)

    class Meta:
        db_table = 'group_members'
        unique_together = ['group', 'user']

class DailyTable(models.Model):    
    class Meta:
        managed = True
        db_table = 'dailytable'

    user_id = models.IntegerField(db_index=True)        
    calories = models.FloatField()        
    date = models.DateField()
我想分别计算各组燃烧的总热量。因此,我启动了以下查询:

 select groups.id,groups.name as group_display_name,
(select count(*) from group_members where group_id = groups.id and status = 'accepted' and groups.group_type_id = 1) as total_members,
(select sum(calories) from dailytable where user_id in (select user_id from group_members where group_id = groups.id and groups.group_type_id = 1) and dailytable.date='2016-02-02') as total_calories,
(select case when exists(select * from group_members where group_id = groups.id and user_id = 3 and status = 'accepted' and groups.group_type_id = 1) then cast(1 as bit) else cast(0 as bit) end) as is_member_of_group
from groups 
where groups.group_type_id = 1
order by total_calories desc 
nulls last;
下面是我得到的输出 现在我想根据我燃烧的总热量对各组进行排名,因此我在查询中做了以下更改:

....
dense_rank() over(order by total_calories)
from groups
....
错误:列“总热量”不存在


我想对查询的输出应用秩。有没有办法做到这一点

这是因为您试图在densite_rank()中使用派生列别名,该别名在那里不可用。在CTE中包装查询并对其应用稠密的_rank():


围绕查询并计算外部选择中的排名

在下面的示例中,查询使用联接和group by而不是子查询来计算总计。

WITH baseQuery AS (
    SELECT
        groups.id,
        groups.name AS group_display_name,
        (
            SELECT
                count(*)
            FROM group_members
            WHERE
                group_id = groups.id AND status = 'accepted' AND groups.group_type_id = 1) AS total_members,
        (
            SELECT
                sum(calories)
            FROM dailytable
            WHERE
                user_id IN (
                    SELECT
                        user_id
                    FROM group_members
                    WHERE
                        group_id = groups.id 
                        AND groups.group_type_id = 1
                ) AND dailytable.date = '2016-02-02'
        ) AS total_calories,
        (
            SELECT
                CASE WHEN exists(SELECT
                                     *
                                 FROM group_members
                                 WHERE
                                     group_id = groups.id 
                                     AND user_id = 3 
                                     AND status = 'accepted' 
                                     AND groups.group_type_id = 1)
                    THEN cast(1 AS BIT)
                ELSE cast(0 AS BIT) END) AS is_member_of_group
    FROM groups
    WHERE
        groups.group_type_id = 1
)
    select * ,
        dense_rank() over(order by total_calories)
    from baseQuery
    ORDER BY total_calories DESC
    NULLS LAST
select 
q.*, 
DENSE_RANK() over (order by total_calories) as total_calories_rank
from
(
    select 
    g.id as group_id, 
    g.name as group_name,
    count(distinct m.user_id) as total_members,
    sum(d.calories) as total_calories,
    cast(max(case when m.user_id = 3 then 1 else 0 end) as bit) as user_3_is_member_of_group
    from groups g
    inner join group_members m on (g.id = m.group_id and m.status = 'accepted')
    left join (
      select user_id, sum(calories) as calories 
      from dailytable
      where date = '2016-02-02'
      group by user_id
    ) d on (m.user_id = d.user_id)
    where g.group_type_id = 1
    group by g.id, g.name
) q
order by total_calories desc 
nulls last;