TO_DATE然后在WHERE中使用BETWEEN

Cop*_*oom 0 sql oracle select

我可以采用下面的SELECT,将24小时的谬误排除在外,用00小时替换它,然后在TRUNC(SYSDATE-90)和TRUNC(SYSDATE)之间运行WHERE TRUNC(TO_DATE(FIX_DATETIME,'MMDDYYHH24MISS'))?可以一次完成吗?如果是这样,无论是通过还是更多,怎么样?非常感谢您的帮助,并且您的技能水平得到尊重.

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
Run Code Online (Sandbox Code Playgroud)

Jus*_*ave 6

暂时搁置一个名为MOPID某个人自然会认为是某种数字ID 的列的不协调实际上VARCHAR2恰好代表了一个DATE事实,即你永远不应该将a存储DATE为a,VARCHAR2因为你将不可避免地最终得到无效该列中的数据将导致查询在查询计划更改时似乎随机开始抛出错误...

WHERE to_date(MOPACTIVITY.MOPID, 'MMDDYYHH24MISS') BETWEEN (sysdate-90) and sysdate
Run Code Online (Sandbox Code Playgroud)

会做你想要的.

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

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;
Run Code Online (Sandbox Code Playgroud)

然后

SELECT *
  FROM MOPACTIVITY
 WHERE is_valid_date( MOPID, 'MMDDYYHH24MISS' ) = 'N'
Run Code Online (Sandbox Code Playgroud)

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