为什么 postgresql case 语句的结果在 where 子句中不起作用

时间:2021-02-08 16:56:18

标签: sql postgresql case where-clause column-alias

我正在解决这个 site 中的一个 PostgreSQL 问题。
我的回答是:

select concat(mem.firstname, ' ', mem.surname), fac.name as facility,
case when mem.memid=0 then bks.slots*fac.guestcost
     else bks.slots*membercost
end  as cost
from cd.members mem
inner join cd.bookings bks on mem.memid=bks.memid
inner join cd.facilities fac on bks.facid=fac.facid

where bks.starttime >= '2012-09-14' and bks.starttime < '2012-09-15' and cost > 30
order by cost desc;

但它显示 ERROR: column "cost" does not exist 子句中的 cost > 30 错误 WHERE。 如果 costORDER BY 内工作,那么为什么它在 WHERE 内不起作用?

The Problem description and database structure

2 个答案:

答案 0 :(得分:1)

这是正确的。您不能使用在 SELECT 中的 WHERE 中定义的列别名。简单的解决方案是使用横向连接来定义列别名:

select concat(mem.firstname, ' ', mem.surname), fac.name as facility,
       v.cost
from cd.members mem join
     cd.bookings bks
     on mem.memid = bks.memid join
     cd.facilities fac
     on bks.facid=fac.facid cross join
     (values (case when mem.memid = 0 then bks.slots * fac.guestcost
                   else bks.slots * membercost
              end)
     ) v(cost)
where bks.starttime >= '2012-09-14' and bks.starttime < '2012-09-15' and
      v.cost > 30
order by v.cost desc;

答案 1 :(得分:0)

您不能在 where 子句中使用任何这样的别名。我使用了选择列表中的条件,而不是 t 别名:

select concat(mem.firstname, ' ', mem.surname), fac.name as facility,
case when mem.memid=0 then bks.slots*fac.guestcost
     else bks.slots*membercost
end  as cost
from cd.members mem
inner join cd.bookings bks on mem.memid=bks.memid
inner join cd.facilities fac on bks.facid=fac.facid

where bks.starttime >= '2012-09-14' and bks.starttime < '2012-09-15' and (case when mem.memid=0 then bks.slots*fac.guestcost
     else bks.slots*membercost
end  ) > 30
order by cost desc;