[英]Ordering VARCHAR2 dates in Oracle
我在VIEW
中有一個列,其中包含格式為'MM / DD / YYYY'的日期值。
如果此列僅包含我列出的格式的日期值,我可以在列上帶有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
添加另一列來完成此操作。
一種方法是手動驗證日期:
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 FIRST
或NULLS LAST
您可以定義非日期值的放置位置。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.