PostgreSQL不接受WHERE子句

时间:2016-06-26 16:26:55

标签: sql postgresql alias operator-precedence

在这个关于加入3个不同表的pgexercises中,答案如下:

select mems.firstname || ' ' || mems.surname as member, 
    facs.name as facility, 
    case 
        when mems.memid = 0 then
            bks.slots*facs.guestcost
        else
            bks.slots*facs.membercost
    end as cost
        from
                cd.members mems                
                inner join cd.bookings bks
                        on mems.memid = bks.memid
                inner join cd.facilities facs
                        on bks.facid = facs.facid
        where
        bks.starttime >= '2012-09-14' and 
        bks.starttime < '2012-09-15' and (
            (mems.memid = 0 and bks.slots*facs.guestcost > 30) or
            (mems.memid != 0 and bks.slots*facs.membercost > 30)
        )
order by cost desc;

为什么我不能在cost子句的SELECT列表中引用WHERE别名?
如果我使用:

运行相同的查询
        ...
        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

由于评估的顺序,我从this answer清楚地了解了它。但为什么order by cost desc;被允许?

1 个答案:

答案 0 :(得分:22)

你问两个问题:
1。

  

为什么我不能在WHERE子句中引用SELECT成本别名?

2

  

但为什么要按成本desc排序;是允许的吗?


manual has an answer for both of them here:

  

输出列的名称可用于引用列的值   ORDER BYGROUP BY条款,但不在WHEREHAVING条款中   条款;那里你必须写出表达式。

它由 SQL标准定义,原因是SELECT查询中的事件序列。在应用WHERE子句时,尚未计算SELECT列表中的输出列。但是当谈到ORDER BY时,输出列很容易获得。

因此,虽然这一开始不方便且令人困惑,但它仍然有意义。

相关: