3

我有一列VIEW包含格式为“MM/DD/YYYY”的日期值。

如果此列仅包含我列出的格式的日期值,我可以ORDER BY在列上执行一个带有 a 的列,TO_DATE以使 VIEW 按该日期排序:

ORDER BY TO_DATE(MY_DATE_COLUMN, 'MM/DD/YYYY') desc

但是,此列中的数据未格式化为“MM/DD/YYYY”。

无论如何只是使用SQL能够对这个被实现为列的列进行排序DATE

我认为这是不可能的,因为数据未格式化为“MM/DD/YYYY”,但我不完全确定......

我也不想在 中添加另一列VIEW来完成此操作。

4

4 回答 4

5

一种方法是手动验证日期:

order by (case when substr(MY_DATE_COLUMN, 1, 2) between '01' and '12' and
                    substr(my_date_column, 3, 1) = '/' and
                    substr(my_date_column, 4, 2) between '01' and '31' and
                    substr(my_date_column, 5, 1) = '/' and
                    substr(my_date_column, 6, 4) between '1900' and '2100' and
                    len(my_date_column) = 10
               then to_date(MY_DATE_COLUMN, 'mm/dd/yyyy')
          end) desc

这对于大多数用途来说可能已经足够了,尽管它允许 2 月 30 日。

您真正想要的是 Oracle 中的 IsDate 函数,但它不可用。

发布后我意识到可能有更简单的方法:

order by substr(my_date_column, 6, 4) desc, substr(MY_DATE_COLUMN, 1, 2) desc,
         substr(my_date_column, 4, 2) desc

它只是提取年、月和日并按降序排序。非日期将被混入,具体取决于它们包含的内容。然而,提问者似乎并不关心顺序,只是简单地消除了语法错误。

于 2012-05-24T21:03:43.183 回答
4

您可以在此列上创建一个函数,尝试转换日期,但捕获任何异常,并按此排序。

您还可以嵌套例外并尝试多种格式进行转换,然后再默认为您选择的某个日期。例如。

CREATE OR REPLACE FUNCTION my2date( p_str in VARCHAR2) RETURN DATE is

BEGIN
      RETURN to_date( p_str, 'MM/DD/YYYY' );
EXCEPTION WHEN OTHERS THEN
    BEGIN
        RETURN to_date( p_str, 'DD/MM/YYYY');
    EXCEPTION WHEN OTHERS THEN
        RETURN sysdate; /* or some other fixed date - depends on if you want these first or last */
    END;
END;
/

然后只需使用该子句:

ORDER BY my2date(MY_DATE_COLUMN) desc;
于 2012-05-24T21:16:18.680 回答
2

如何修复数据,并添加触发器以防止进一步的错误数据...或添加适当的日期列而不是 varchar ...

于 2012-05-24T21:23:32.990 回答
2

实现这一点的最简单方法可能是定义您自己的to_date()函数,该函数返回 null(或任何其他默认值,如sysdate)。这是可能的,因为to_date当它无法处理输入值时会简单地引发异常。

CREATE OR REPLACE FUNCTION to_date_null(date_str IN varchar2, format_mask IN varchar2)
RETURN DATE
IS
  l_date DATE;
BEGIN
  l_date := to_date( date_str, format_mask );
  RETURN l_date;
EXCEPTION
  WHEN others THEN
    RETURN null;
END to_date_null;

然后你可以在你的order by子句中使用这个函数

order by to_date_null(MY_DATE_COLUMN, 'MM/DD/YYYY') desc NULLS LAST;

通过指定NULLS FIRSTNULLS LAST您可以定义放置非日期值的位置。

于 2012-05-24T21:25:18.533 回答