首先。抱歉标题含糊不清。我不知道如何构建它。通过示例代码,我希望你能理解我的疑虑。
任务是找出俱乐部收入排名前三的设施。我以为这是最后的代码。
SELECT x,y as rank
FROM tableA
where rank <=3;
但这说明等级栏并不存在。因此,我必须将其包含在另一个子查询中,以筛选前3名。
SELECT x,rank
FROM
(SELECT x,y as rank
FROM tableA
) as sub
where rank<=3;
为什么?我需要一个额外的子查询吗?为什么它不能在原始查询中使用where子句进行筛选?
设施名称代码及其收入排名:
select res.name,rank() over(order by total desc) as rank
from
(select fac.facid,fac.name,sum(slots*
case
when memid=0 then guestcost
else membercost
end) as total
from cd.bookings bks
inner join cd.facilities fac
on bks.facid=fac.facid
group by fac.facid
order by total desc) as res
我认为可行的方法:
select res.name,rank() over(order by total desc) as rank
from
(select fac.facid,fac.name,sum(slots*
case
when memid=0 then guestcost
else membercost
end) as total
from cd.bookings bks
inner join cd.facilities fac
on bks.facid=fac.facid
group by fac.facid
order by total desc) as res
where rank<=3;
(why this don't work??)
工作原理:
select name, rank
from
(select res.name,rank() over(order by total desc) as rank
from
(select fac.facid,fac.name,sum(slots*
case
when memid=0 then guestcost
else membercost
end) as total
from cd.bookings bks
inner join cd.facilities fac
on bks.facid=fac.facid
group by fac.facid
order by total desc) as res) as sub
where rank <=3;
考虑您的第一个查询版本:
SELECT x, RANK() OVER (ORDER BY y) rnk
FROM tableA
WHERE rnk <= 3;
这是不合法的,因为不能在WHERE
子句中使用在同一级别的SELECT
中定义的别名。这里的问题是,执行的窗口函数通常在WHERE
子句中进行筛选之前执行最后。相反,您需要计算子查询中的排名,然后对其进行过滤:
SELECT *
FROM
(
SELECT x, RANK() OVER (ORDER BY y) rnk
FROM tableA
) t
WHERE rnk <= 3;
请注意,SQL的某些版本确实允许在QUALIFY
子句中使用窗口函数:
SELECT x, RANK() OVER (ORDER BY y) rnk
FROM tableA
QUALIFY RANK() OVER (ORDER BY y) <= 3;
但是Postgres不支持QUALIFY
,所以您可能需要使用子查询选项。