0

我可以在下面使用这个 SELECT,去掉 24 小时的谬误并将其替换为 00 小时,然后运行 ​​WHERE TRUNC(TO_DATE(FIX_DATETIME, 'MMDDYYHH24MISS')) BETWEEN TRUNC(SYSDATE-90) AND TRUNC(SYSDATE)?可以一次性完成吗?如果是这样,无论是通过还是更多,如何?非常感谢您的帮助,并尊重您的技能水平。

SELECT MOPACTIVITY.MOPID,
    (CASE 
        WHEN SUBSTR(MOPACTIVITY.MOPID, 7, 2) = '24' THEN SUBSTR(MOPACTIVITY.MOPID, 1, 2)||SUBSTR(MOPACTIVITY.MOPID, 3, 2)||SUBSTR(MOPACTIVITY.MOPID, 5, 2)||'00'||SUBSTR(MOPACTIVITY.MOPID, 9, 2)||SUBSTR(MOPACTIVITY.MOPID, 11, 2)
        ELSE MOPACTIVITY.MOPID
    END ) FIX_DATETIME,
sysdate "SYSDATE"
FROM MOPUSER.MOPACTIVITY
4

2 回答 2

5

暂且不谈一个名为的列的不协调性MOPID,有人自然会认为它是某种数字 ID 实际上是 aVARCHAR2恰好代表 aDATE以及您永远不应该将 a 存储DATE为 a的事实,VARCHAR2因为您将不可避免地以 invalid 告终当查询计划更改时,该列中的数据将导致查询开始随机抛出错误......

WHERE to_date(MOPACTIVITY.MOPID, 'MMDDYYHH24MISS') BETWEEN (sysdate-90) and sysdate

会做你想做的事。

识别具有无效数据的行(当您使用错误的数据类型时几乎可以确定)

CREATE OR REPLACE FUNCTION is_valid_date( p_str IN VARCHAR2,
                                          p_mask IN VARCHAR2 )
  RETURN VARCHAR2
IS
  l_dt  DATE;
BEGIN
  l_dt := to_date( p_str, p_mask );
  RETURN 'Y';
EXCEPTION
  WHEN OTHERS THEN
    RETURN 'N';
END;

接着

SELECT *
  FROM MOPACTIVITY
 WHERE is_valid_date( MOPID, 'MMDDYYHH24MISS' ) = 'N'

SUBSTR您可以尝试使用正则表达式或尝试INSTR各种组件来查找无效数据。然而,这种方法只能是近似的,除非您想尝试实施所有可能的日历规则(即 29-31 是某些月份和某些年份的有效日期,但不是其他日期)。to_date简单地尝试转换并依靠 Oracle 来实现所有这些规则通常更容易。

于 2013-06-10T18:57:22.233 回答
0

如果您正在寻找日期比较,您应该使用:

WHERE to_date(MOPACTIVITY.MOPID, 'MMDDYYHH24MISS') BETWEEN trunc(sysdate-90) and trunc(sysdate)

或者

WHERE to_date(substr(MOPACTIVITY.MOPID, 1, 6), 'MMDDYY') BETWEEN trunc(sysdate-90) and trunc(sysdate)

这假设您想要完整的日子,包括当天(部分到当前时间)和从午夜开始的第一天(不是当前时间)。

于 2013-06-10T19:02:36.793 回答