我正在尝试转换查看月份的现有 CASE 表达式,而不是让它查看确切的日期。
CASE
WHEN reg_con * tagg_reading <60 and to_char(read_date,'mm') in ('06','07','08','09') then 'Y'
WHEN reg_con * tagg_reading <90 and to_char(read_date,'mm') in ('01','02','03','04','05','10','11','12') then 'Y'
ELSE 'N'
END as Keep_Flag
我的更改已运行,但结果不正确
CASE
WHEN reg_con * tagg_reading <60 and to_char(read_date, 'MM-DD') BETWEEN '6-15' AND '10-15' then 'Y'
WHEN reg_con * tagg_reading <90 and to_char(read_date, 'MM-DD') BETWEEN '10-16' AND '6-14' then 'Y'
ELSE 'N'
END as Keep_Flag
感谢任何调整帮助。
CASE 表达式的结果用于过滤 WHERE 语句中的数据
WHERE keep_flag = 'Y'
您的第二种情况表达式有两个直接问题。
首先,默认情况下日期元素是用零填充的,因此如果
read_date
是 2024-06-15,则转换 to_char(read_date, 'MM-DD')
将给出“06-15”,而不是“6-15”。
其次,值的顺序对于
BETWEEN
很重要,如文档中所述:
如果 expr3 < expr2, then the interval is empty.
因此,当与字符串进行比较时,“6-15”和“10-15”之间不会有任何日期值,因为“1”按字母顺序排在“6”之前 - 并且没有任何内容匹配
BETWEEN '6' AND '1'
,因为“1”(expr3)< '6' (expr2) which makes that interval empty.
某些值将在“10-16”和“6-14”之间匹配,但仅匹配“12-31”以内的值,因此只有您要查找的范围的大约一半。一月到九月之间的任何内容都会有第一个字符“0”,因此不会在该范围内。
您可以使用两位数的月份数字将第二场比赛分成两部分:
CASE
WHEN reg_con * tagg_reading <60 and to_char(read_date, 'MM-DD') BETWEEN '06-15' AND '10-15' then 'Y'
WHEN reg_con * tagg_reading <90 and to_char(read_date, 'MM-DD') BETWEEN '01-01' AND '06-14' then 'Y'
WHEN reg_con * tagg_reading <90 and to_char(read_date, 'MM-DD') BETWEEN '10-16' AND '12-31' then 'Y'
ELSE 'N'
END as Keep_Flag
或者您可以保留一个范围,但使用
NOT BETWEEN
来排除“06-15”到“10-16”范围:
CASE
WHEN reg_con * tagg_reading <60 and to_char(read_date, 'MM-DD') BETWEEN '06-15' AND '10-15' then 'Y'
WHEN reg_con * tagg_reading <90 and to_char(read_date, 'MM-DD') NOT BETWEEN '06-15' AND '10-15' then 'Y'
ELSE 'N'
END as Keep_Flag
这看起来仍然很奇怪,但是没有样本数据和预期结果,不清楚它是否会达到您真正想要的效果。一般来说,最好将日期与日期(或日期范围)进行比较,但您忽略了年份,这是一个问题。您也可以用季度数字做一些事情,在转换进行比较之前在值中添加天数,但同样不清楚。
我尝试重现您的问题,假设 read_date 的格式为 DD-MM-YY。您的查询正在比较字符串。
您可以像这样使用
TO_DATE
TO_DATE(TO_CHAR(read_date, 'MM-DD'), 'MM-DD') BETWEEN TO_DATE('06-15', 'MM-DD') AND TO_DATE('10-15', 'MM-DD')
对于第二个条件
BETWEEN '10-16' AND '6-14'
您打算添加 10 月 16 日至 6 月 14 日之间的日期还是反之亦然,即 6 月 14 日至 10 月 16 日之间的日期。我假设您想添加 10 月 16 日至 6 月 14 日之间的日期,因为 6 月至 10 月包含在第一个条件。
AND (TO_CHAR(read_date, 'MM-DD') BETWEEN '10-16' AND '12-31' OR TO_CHAR(read_date, 'MM-DD') BETWEEN '01-01' AND '06-14') THEN 'Y'
示例输入
身份证 | REG_CON | TAGG_READING | 阅读_日期 |
---|---|---|---|
1 | 1 | 10 | 24 年 6 月 20 日 |
2 | 4 | 20 | 24 年 4 月 10 日 |
3 | 4 | 30 | 24 年 8 月 15 日 |
4 | 4 | 40 | 24 年 12 月 25 日 |
5 | 3 | 50 | 24 年 10 月 5 日 |
SELECT id, reg_con, tagg_reading, read_date,
CASE
WHEN reg_con * tagg_reading < 60
AND TO_CHAR(read_date, 'MM-DD') BETWEEN '06-15' AND '10-15' THEN 'Y'
WHEN reg_con * tagg_reading < 90
AND (TO_CHAR(read_date, 'MM-DD') BETWEEN '10-16' AND '12-31' OR TO_CHAR(read_date, 'MM-DD') BETWEEN '01-01' AND '06-14') THEN 'Y'
ELSE 'N'
END AS Keep_Flag
FROM test;
输出
身份证 | REG_CON | TAGG_READING | 阅读_日期 | KEEP_FLAG |
---|---|---|---|---|
1 | 1 | 10 | 24 年 6 月 20 日 | 是 |
2 | 4 | 20 | 24 年 4 月 10 日 | 是 |
3 | 4 | 30 | 24 年 8 月 15 日 | N |
4 | 4 | 40 | 24 年 12 月 25 日 | N |
5 | 3 | 50 | 24 年 10 月 5 日 | N |