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-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 ;
出现错误:
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_date
和 end_date
也是日期。如果它们是字符串(它们不应该是),则 P_date
不需要转换,但是比较不会像您预期的那样使用您的格式 seeing/using.
我有一份每月或每年或两者都会更新的产品清单。如果续订值为 '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 ;
出现错误:
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_date
和 end_date
也是日期。如果它们是字符串(它们不应该是),则 P_date
不需要转换,但是比较不会像您预期的那样使用您的格式 seeing/using.