我在VIEW
中有一个列,其中包含格式为'MM / DD / YYYY'的日期值。
如果此列仅包含我列出的格式的日期值,我可以在列上ORDER BY
的{{1}}上执行TO_DATE
,以使VIEW按该日期排序:
ORDER BY TO_DATE(MY_DATE_COLUMN, 'MM/DD/YYYY') desc
但是,此列中的数据未格式化为“MM / DD / YYYY”。
是否只是使用SQL
才能对此列进行排序,并将其视为DATE
列?
我认为由于数据未被格式化为'MM / DD / YYYY'而无法实现,但我并不完全确定......
我不想在VIEW
中添加其他列来完成此操作。
答案 0 :(得分: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
它只提取年,月,日和降序。非日期将混合在一起,具体取决于它们包含的内容。然而,提问者似乎并不关心顺序,只是简单地消除了语法错误。
答案 1 :(得分: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;
答案 2 :(得分:2)
如何修复数据,并添加触发器以防止进一步的错误数据...... 或添加适当的日期列而不是varchar ...
答案 3 :(得分: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 FIRST
或NULLS LAST
,您可以定义非日期值的放置位置。