簡體   English   中英

在Oracle中訂購VARCHAR2日期

[英]Ordering VARCHAR2 dates in Oracle

我在VIEW中有一個列,其中包含格式為'MM / DD / YYYY'的日期值。

如果此列僅包含我列出的格式的日期值,我可以在列上帶有TO_DATEORDER BY ,以使VIEW按該日期排序:

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

但是,此列中的數據未格式化為“MM / DD / YYYY”。

反正只是使用SQL才能對此列進行排序,實現為DATE列?

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

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

一種方法是手動驗證日期:

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

它只提取年,月,日和降序。 非日期將混合在一起,具體取決於它們包含的內容。 然而,提問者似乎並不關心順序,只是簡單地消除了語法錯誤。

您可以在此列上創建一個函數來嘗試轉換日期,但捕獲任何異常,並按此排序。

您還可以嵌套異常並嘗試多種格式進行轉換,然后默認為您選擇的某個日期。 例如。

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;

如何修復數據,並添加觸發器以防止進一步的錯誤數據...或添加適當的日期列而不是varchar ...

實現此目的的最簡單方法可能是定義自己的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您可以定義非日期值的放置位置。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM