在查询的输出上应用 DENSE_RANK()
To apply DENSE_RANK() on the output of an query
我有三个表,分别名为 Groups、GroupMembers 和 DailyTable。以下是我对它们中的每一个的模型:
models.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;
下面是我得到的输出
现在我想根据我烧毁的 total_calories 对组进行排名,所以我在查询中进行以下更改:
....
dense_rank() over(order by total_calories)
from groups
....
错误:列"total_calories"不存在
我想将排名应用于查询的输出。有什么办法可以做到这一点。
这是因为您正试图在 dense_rank() 中使用派生列别名,而该别名在那里不可用。在 CTE 中包装查询并在其上应用 dense_rank():
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中的排名。
在下面的示例中,查询使用联接和分组而不是子查询来计算总计。
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;
我有三个表,分别名为 Groups、GroupMembers 和 DailyTable。以下是我对它们中的每一个的模型:
models.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
....
错误:列"total_calories"不存在
我想将排名应用于查询的输出。有什么办法可以做到这一点。
这是因为您正试图在 dense_rank() 中使用派生列别名,而该别名在那里不可用。在 CTE 中包装查询并在其上应用 dense_rank():
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中的排名。
在下面的示例中,查询使用联接和分组而不是子查询来计算总计。
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;