比较两个日期Oracle的多案例
Posted
技术标签:
【中文标题】比较两个日期Oracle的多案例【英文标题】:Multi case when for compare two dates Oracle 【发布时间】:2021-06-30 16:50:07 【问题描述】:我有一个 sql 查询,它使用“case when”来比较两个日期然后赋值,我的代码有效,但我想知道我是否可以将日期计算为 case 语句,然后只在WHEN 语句。
代码有效:
SELECT
O.ID
CASE
WHEN TO_DATE(SYSDATE) - TO_DATE(O.CREATED_AT) BETWEEN 1 AND 10 THEN 'start'
WHEN TO_DATE(SYSDATE) - TO_DATE(O.CREATED_AT) BETWEEN 11 AND 15 THEN 'proccesing'
WHEN TO_DATE(SYSDATE) - TO_DATE(O.CREATED_AT) BETWEEN 16 AND 30 THEN 'finish'
ELSE 'expired'
END AS State
FROM ORDER O
WHERE O.STATE > 2
下一个代码抛出下一个错误“SQL 错误 [923] [42000]: ORA-00923: FROM keyword not found where expected”
SELECT
O.ID
CASE TO_DATE(SYSDATE) - TO_DATE(O.CREATED_AT) as totaldays
WHEN totaldays BETWEEN 1 AND 10 THEN 'start'
WHEN totaldays BETWEEN 11 AND 15 THEN 'proccesing'
WHEN totaldays BETWEEN 16 AND 30 THEN 'finish'
ELSE 'expired'
END AS State
FROM ORDER O
WHERE O.STATE > 2
我的目标是每行计算一次,这比对每个“案例”句子进行计算更好吗?性能有没有区别?
有没有办法计算一次,然后评估结果?
【问题讨论】:
第二个不是有效的 SQL,所以它不是一个选项。坚持运行的代码。 在 SQL 表达式或内置函数中性能并非如此,因为大部分时间都花在读取、排序、连接和聚合数据上 O.ID 后面需要一个逗号... 不要使用to_date(sysdate); sysdate 已经是一个日期。我怀疑这同样适用于 created_at 列。如果列/变量已经是日期,则永远不需要转换为日期,实际上可能会发生非常难以发现的奇怪错误。 我正要说 :-)TO_DATE
存在将字符串转换为日期时间(Oracle 不恰当地调用 DATE
)。也许你想要 TRUNC(SYSDATE)
和 TRUNC(O.CREATED_AT)
代替。从日期时间中删除时间部分
【参考方案1】:
在派生表中执行TO_DATE
的内容,这样您就可以节省一些输入,而且代码容易出错:
SELECT ID,
CASE WHEN totaldays BETWEEN 1 AND 10 THEN 'start'
WHEN totaldays BETWEEN 11 AND 15 THEN 'proccesing'
WHEN totaldays BETWEEN 16 AND 30 THEN 'finish'
ELSE 'expired'
END AS State
FROM
(
SELECT
O.ID,
TRUNC(SYSDATE) - TRUNC(O.CREATED_AT) as totaldays
FROM ORDER O
WHERE O.STATE > 2
) dt
顺便说一句,ORDER
是 SQL 保留字,因此表名必须限定为 "ORDER"
。 (https://en.wikipedia.org/wiki/SQL_reserved_words.)
编辑: astentx 建议简化为:
SELECT ID,
CASE WHEN totaldays <= 10 THEN 'start'
WHEN totaldays <= 15 THEN 'proccesing'
WHEN totaldays <= 30 THEN 'finish'
ELSE 'expired'
END AS State
FROM
(
SELECT
O.ID,
TRUNC(SYSDATE) - TRUNC(O.CREATED_AT) as totaldays
FROM ORDER O
WHERE O.STATE > 2
) dt
【讨论】:
between
可以进一步缩短为<= upper_boundary
@astentx,当然......我会在答案中添加那个版本!
还有to_date(sysdate)
...没有cmets)
你的意思是应该是sysdate - TO_DATE(O.CREATED_AT)
? (我从未使用过 Oracle,我只是想向 OP 展示派生表的技巧......)
他们可能想要删除时间部分,以便从另一个日期中减去一个日期并获得完整天数(整数),因此:TRUNC(SYSDATE) - TRUNC(O.CREATED_AT) as totaldays
。以上是关于比较两个日期Oracle的多案例的主要内容,如果未能解决你的问题,请参考以下文章