I have this SQL
SELECT
price_amount,
price_currency,
CASE
WHEN price_currency='USD' THEN price_amount * 3.9024
WHEN price_currency='EUR' THEN price_amount * 4.413
WHEN price_currency='ILS' THEN price_amount * 1
ELSE price_amount * 1
END AS final_price
FROM items
WHERE final_price BETWEEN 1 AND 100
but I get:
ERROR: column "final_price" does not exist
LINE 1: …ce_amount * 1 END AS final_price FROM items WHERE final_pric…
It is getting selected using alias, so why is it trying to find it in the table?
Best Answer
The WHERE clause is evaluated before aliases in the
SELECT
clause.WHERE
is used to locate rows from the base table which are the input to all expressions in theSELECT
. Only after locating the rows yourCASE
can be evaluated with real values and thefinal_price
alias is assigned its value.There are multiple ways to solve that:
WHERE
clause - that way it will be used to locate the rowsWHERE
to the outer query - as you select from a derived table, the alias becomes a "real" column that wayHAVING
clause instead of WHERE -HAVING
(in MySQL) works after theSELECT
is computed to do a "second wave" of filtering. In standard SQL (and in Postgres),SELECT
is logically processed afterHAVING
, so this won't work.CASE
expression, that way it becomes a part of your base table and you might even be able to index itWarning: your query will need to do fulltable/index scan unless you can add some "simpler"
WHERE
conditions or be able to use the indexed virtual column.