我有每月或每年更新的产品列表,或者两者都有。如果续订值为"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-2022
,选择renew
作为M
,则应选择P_no
1001
作为
如果我选择P_date
作为06-01-2022
,选择renew
作为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 ;
并得到错误:
缺少关键字
我做错了什么?
您正试图根据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_date
和end_date
也是日期。如果它们是字符串(而且不应该是(,那么P_date
就不需要转换,但在您看到/使用的格式下,比较不会像您预期的那样工作。
您的案例陈述不正确。要么你这样做:
CASE
WHEN renew = 'M'
或
CASE renew
WHEN 'M'