PostgreSQL不接受WHERE子句中的列别名

Lam*_*mnk 10 sql postgresql alias operator-precedence

在这种pgexercises有关加入3页不同的表,给出的答案是如下:

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;
Run Code Online (Sandbox Code Playgroud)

为什么我不能在子句costSELECT列表中引用别名WHERE
如果我运行相同的查询:

        ...
        where
        bks.starttime >= '2012-09-14' and 
        bks.starttime < '2012-09-15' and
        cost > 30
order by cost desc;
Run Code Online (Sandbox Code Playgroud)

发生错误:

ERROR: column "cost" does not exist
Run Code Online (Sandbox Code Playgroud)

这个答案我很清楚,这是因为评估的顺序.但为什么order by cost desc;允许?

Erw*_*ter 22

你问两个问题:
1.

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

2.

但为什么要按成本规定排序; 被允许?


手册对他们两人在这里的答案:

输出列的名称可用于引用列的值in ORDER BYGROUP BY子句,但不能用于WHEREHAVING 子句; 那里你必须写出表达式.

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

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

有关: