WHERE CLAUSE 中的 CASE 语句 - 缺少关键字错误

CASE statement in WHERE CALUSE - Missing keyword error

我有一份每月或每年或两者都会更新的产品清单。如果续订值为 'M',则产品按月续订。如果续订值为 'Y',则产品按年续订。

所以我的查询是,如果我选择方法(M/Y)和特定日期(P_date),我想要符合续订条件的产品的详细信息。

例如:

P_no    start_date   renewal_date   end_date     
1001    01-01-2022   01-02-2022     31-01-2022    
1002    01-01-2022   01-01-2023     31-12-2022

如果我选择 P_date 作为 06-01-2022renew 作为 M 那么应该选择 P_no 1001

如果我选择 P_date 作为 06-01-2022renew 作为 A 那么应该选择 P_no 1002

我写了下面的查询

select * from products 
where P_no in('1001','1002') and 
CASE renew
   WHEN renew = 'M' and round(months_between(renewal_date,start_date)) = 1 then
        TO_CHAR(TO_DATE (P_date,'DD-MM-YYYY'),'DD-MON-YYYY') BETWEEN  start_date AND  end_date
    WHEN renew='Y' and round(months_between(renewal_date,start_date)) = 12 then 
        TO_CHAR(TO_DATE (P_date,'DD-MM-YYYY'),'DD-MON-YYYY') BETWEEN start_date AND end_date
    end   ;

出现错误:

Missing Keyword

我做错了什么?

您的案例陈述不正确。要么你做这样的事情:

CASE  
   WHEN renew = 'M'  

CASE renew
 WHEN  'M'  

您正在尝试更改应用于基于 case 表达式的查询的条件,但这不起作用;你 可以 计算结果为 0/1 并与 than 进行比较,但这只会让它更难阅读。

相反,只需对整个事情使用布尔逻辑;假设 renew 只能是 M 或 Y 那么也许:

select * from products 
where P_no in('1001','1002') and 
(
  (
    renew = 'M' and round(months_between(renewal_date,start_date)) = 1 and
        TO_CHAR(TO_DATE (P_date,'DD-MM-YYYY'),'DD-MON-YYYY') BETWEEN  start_date AND  end_date
  )
  or
  (
    renew='Y' and round(months_between(renewal_date,start_date)) = 12 and 
        TO_CHAR(TO_DATE (P_date,'DD-MM-YYYY'),'DD-MON-YYYY') BETWEEN start_date AND end_date
  )
);

或者也许:

select * from products 
where P_no in('1001','1002') and 
(
  (renew = 'M' and round(months_between(renewal_date,start_date)) = 1)
  or
  (renew='Y' and round(months_between(renewal_date,start_date)) = 12)
)
and TO_CHAR(TO_DATE (P_date,'DD-MM-YYYY'),'DD-MON-YYYY') BETWEEN  start_date AND  end_date;

尽管您对 p_date 的转换看起来很奇怪。如果那是日期数据类型(如果可能的话,它应该是)那么就这样做:

P_date BETWEEN  start_date AND end_date

如果是字符串,则将其转换为日期,但不要再转换回字符串:

TO_DATE (P_date,'DD-MM-YYYY') BETWEEN  start_date AND end_date

当然,假设 start_dateend_date 也是日期。如果它们是字符串(它们不应该是),则 P_date 不需要转换,但是比较不会像您预期的那样使用您的格式 seeing/using.