在 WHERE 子句中使用 CASE 表达式时,列不存在

Nic*_*nto 1 postgresql

我有这个 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
Run Code Online (Sandbox Code Playgroud)

但我得到:

错误:“final_price”列不存在第
1 行:...ce_amount * 1 END AS final_price FROM items WHERE final_pric...

它使用别名被选中,那么为什么它试图在表中找到它?

jka*_*lik 6

WHERE 子句在子句中的别名之前进行评估SELECTWHERE用于从基表中定位行,这些行是SELECT. 只有在找到行后,您CASE才能使用实际值进行评估,并为final_price别名分配其值。

有多种方法可以解决:

  • WHERE子句中重复相同的表达式- 这样它将用于定位行
  • 将您的查询包装为另一个查询中的子查询并将其移动WHERE到外部查询 - 当您从派生表中进行选择时,别名就变成了“真实”列
  • (这在 MySQL 中有效,但在PostgreSQL 中无效)使用HAVING子句而不是 WHERE - HAVING(在 MySQL 中)在SELECT计算后进行“第二波”过滤工作。在标准 SQL(和 Postgres)中,SELECT在 之后进行逻辑处理HAVING,所以这不起作用。
  • 从您的CASE表达式创建一个生成/虚拟列,这样它就成为您基表的一部分,您甚至可以对其进行索引

警告:除非您可以添加一些“更简单”的WHERE条件或能够使用索引虚拟列,否则您的查询将需要进行全表/索引扫描。