2014-09-22 77 views
3

請您在Oracle中讓我知道一個查詢來查找10行中最大的三列。SQL查詢在列和行中查找最大值

要求是我有三個日期列,我需要找到10行中最大的三列。我知道最偉大的人會在一行中找到。

任何查詢都會對此有所幫助,我使用的是oracle 11g。

+0

因此,您想要所有30個值的最大值?或者你想要每欄最大的價值(總共三個價值)? – 2014-09-22 15:12:24

回答

3

如何

select max(greatest(date1, date2, date3, date4)) from my_table; 
+0

我不太確定你有多少日期列。你在第一句中提到4列,但在第二句中提到3個日期欄。 – pjd 2014-09-22 15:10:55

+0

這是一個更好的方法 – FuzzyTree 2014-09-22 15:17:36

+0

除了使用nvl之外,是否有值來忽略空值?我想忽略最大的列。 – Hari 2014-09-22 17:51:23

2

您可以再次使用greatestorder by

select * from (
    select greatest(c1,c2,c3,c4) from mytable 
    order by greatest(c1,c2,c3,c4) desc 
) t1 where rownum = 1 
1
With data as(
    Select col1 dt from table union all 
    Select col2 from table union all 
    Select col3 from table union all 
    Select col4 from table 
) 
Select max(dt) max_dt 
    from data 
/

假設4列DATE數據類型。 它只使用MAX,而不是GREATEST

更新:通過擴展提到@Thorsten好點的在下面的評論

GREATEST()功能的問題是,當你需要處理NULL值傳遞給它,你必須使用NVL以獲得適當的輸出。關於這個問題有很多問題,比如「如何避免使用最高功能的NULL值」等。

注意:從性能的角度來看,請在生產環境中應用此類邏輯之前進行測試。

+1

因此避免了GREATEST的NULL問題。它速度較慢,但​​符合要求。 +1 – 2014-09-22 18:50:43

+0

@Thorsten,兩個好點。感謝提及。發佈答案時,我的腦海中已經存在NULL問題。但是,關於查詢的性能,我會非常關心。但是隨着更新的版本和更好的硬件,我的擔心實際上不是什麼大不了的事情。但是,遺留系統可能效率不高。 – 2014-09-22 18:58:17

0

這裏有兩種方法來規避GREATEST的NULL問題(即,當所有值爲NULL時GREATEST不僅返回NULL,而且至少有一個值爲空時,這使得GREATEST工作常常是一種討厭的問題)。

對於n列,您可以使用n個COALESCE表達式。每個表達式都必須包含所有列,每個列都以不同的列開始。

select 
    max(
    greatest(
     coalesce(col1,col2,col3,col4),  
     coalesce(col2,col3,col4,col1), 
     coalesce(col3,col4,col1,col2),  
     coalesce(col4,col1,col2,col3) 
    ) 
) 
from mytable; 

另一種方法是根本不使用GREATEST,但與CASE和COALESCE比較。每個值都與所有其他值進行比較。 col1 >= coalesce(col2,col1)確保col1被視爲大於或等於expresson,當col2爲NULL時,只要col1本身不爲NULL。在CASE中,所有列都是NULL,CASE表達式默認爲NULL。 (可以添加else NULL以使這對未經驗的閱讀器可見)。

select 
    max(
    case 
     when col1 >= coalesce(col2,col1) and col1 >= coalesce(col3,col1) and col1 >= coalesce(col4,col1) then col1 
     when col2 >= coalesce(col1,col2) and col1 >= coalesce(col3,col2) and col1 >= coalesce(col4,col2) then col2 
     when col3 >= coalesce(col1,col3) and col1 >= coalesce(col2,col3) and col1 >= coalesce(col4,col3) then col3 
     when col4 >= coalesce(col1,col4) and col1 >= coalesce(col2,col4) and col1 >= coalesce(col3,col4) then col4 
    end 
) 
from mytable;