2012-05-24 50 views
3

我在VIEW中有一列包含'MM/DD/YYYY'格式的日期值。在Oracle中訂購VARCHAR2日期

如果此列只在我列出的格式包含日期值,我可以在上面有一個TO_DATE列做一個ORDER BY得到VIEW通過日期排序:

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

然而,有此列中未格式化爲「MM/DD/YYYY」的數據。

無論如何只要使用SQL就可以在此列上排序實現爲DATE列?

我認爲這是不可能的,因爲沒有被格式化爲「MM/DD/YYYY」的數據,但我並不完全確定...

我不希望添加VIEW中的另一列也可以實現此目的。

+5

垃圾進出垃圾。如果你的數據不一致,我不認爲有一個神奇的SQL命令將決定它應該是什麼。 – JNK

+1

嗯 - 問一個合法的編程問題downvotes?如果答案是「否」,那麼爲什麼不說,然後解釋爲什麼...... –

+1

爲什麼它值得我沒有downvote。 – JNK

回答

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; 
4

一種方法是手動確認日期:

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 

它只是中提取年,月,日和排序下降:

我張貼這有可能是一個更簡單的方法實現之後。非日期會混入,取決於它們包含的內容。但是,提問者似乎不關心順序,只是簡單地消除了語法錯誤。

+0

謝謝 - 這看起來像要走的路 - 我會試驗它 –

2

怎麼樣修復數據,並添加觸發器以防止進一步的壞數據... 或添加適當的日期列,而不是爲varchar。 ..

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您可以定義一個非日期值被放置。