TO_DATE然后在WHERE中使用BETWEEN

时间:2013-06-10 18:53:40

标签: 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

2 个答案:

答案 0 :(得分:6)

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

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'

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

答案 1 :(得分:0)

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

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)

这假定您需要完整的日期,包括当天(部分截至当前时间)和午夜的第一天(不是当前时间)。