Oracle:在Where子句中使用Case语句

时间:2017-03-28 12:56:06

标签: sql oracle case

在Oracle 12(和APEX)中,我在WHERE子句中遇到CASE语句问题。该场景是主表,ORDER和PRODUCTS_BOUGHT表,因此这是一对多的关系。我有一份报告,有过PRODUCTS_BOUGHT的过滤器。过滤器填充名为P36_PRODUCT_LISTING的绑定变量/ APEX页面项。如果用户选择给定产品,我希望报告只显示包含给定产品的订单。过滤条件包含“全部”字样,不应进行任何过滤,以及我们随身携带的每件商品。

我的SQL语句是

Select distinct   
    :P36_PRODUCT_LISTING,    
     LISTAGG(product_name, ', ') WITHIN GROUP (ORDER BY product_name)   OVER (PARTITION BY B.SALES_ORDER_NUMBER) AS products,
    ...
from ORDER A, PRODUCTS_BOUGHT B
where 
 A.SALES_ORDER_NUMBER = B.SALES_ORDER_NUMBER
 and
case when
 :P36_PRODUCT_LISTING = 'All' then 1 = 1
else a.SALES_ORDER_NUMBER IN (SELECT SALES_ORDER_NUMBER from PRODUCTS_BOUGHT where PRODUCT_NAME = :P36_PRODUCT_LISTING) end 

当我运行语句时,我得到的错误是Missing Keyword。 我做错了什么?

2 个答案:

答案 0 :(得分:2)

请勿使用case。只需使用布尔逻辑:

where (:P36_PRODUCT_LISTING = 'All' or
       a.SALES_ORDER_NUMBER IN (SELECT SALES_ORDER_NUMBER
                                from PRODUCTS_BOUGHT
                                where PRODUCT_NAME = :P36_PRODUCT_LISTING
                               ) 
      ) 

case(正如您所写)的问题是Oracle不会将逻辑表达式中的值视为有效值。有些数据库可以,但不是Oracle。

另外:

  • 请勿在{{1​​}}子句中使用逗号。始终使用正确的,明确的from语法。
  • 使用表别名缩写的表别名。更容易阅读查询和修复错误。
  • 这里不需要
  • join。您正在进行没有select distinct的聚合,因此无论如何只有一行。

所以:

group by

答案 1 :(得分:0)

Case旨在返回一个值,而不是一个声明..

尝试OR而不是

where :P36_PRODUCT_LISTING = 'All' 
or (:P36_PRODUCT_LISTING <> 'All'
    and a.SALES_ORDER_NUMBER IN (SELECT SALES_ORDER_NUMBER from PRODUCTS_BOUGHT where PRODUCT_NAME = :P36_PRODUCT_LISTING))