简体   繁体   中英

How to get min value from multiple columns for a row in SQL

I need to get to first (min) date from a set of 4 (or more) columns.

I tried

select min (col1, col2, col3) from tbl

which is obviouslly wrong.

let's say I have these 4 columns

col1     |  col2     | col3  |  col4
1/1/17   | 2/2/17    |       | 3/3/17

... in this case what I want to get is the value in col1 (1/1/17). and Yes, these columns can include NULLs.

I am running this in dashDB

the columns are Date data type,

there is no ID nor Primary key column in this table,

and I need to do this for ALL rows in my query,

the columns are NOT in order. meaning that col1 does NOT have to be before col2 or it has to be null AND col2 does NOT have to be before col3 or it has to be NULL .. and so on

If a id column in your table. Then

Query

select t.id, min(t.col) as min_col_value from(
    select id, col1 as col from your_table
    union all
    select id, col2 as col from your_table
    union all
    select id, col3 as col from your_table
    union all
    select id, col4 as col from your_table
)t
group by t.id;

If your DB support least function, it is the best approach

select 

least 
(
nvl(col1,TO_DATE('2901-01-01','YYYY-MM-DD')),
nvl(col2,TO_DATE('2901-01-01','YYYY-MM-DD')),
nvl(col3,TO_DATE('2901-01-01','YYYY-MM-DD')),
nvl(col4,TO_DATE('2901-01-01','YYYY-MM-DD'))
)
from tbl

Edit: If all col(s) are null, then you can hardcode the output as null . The below query should work. I couldn't test it but this should work.

select 
case when 
    least 
    (
    nvl(col1,TO_DATE('2901-01-01','YYYY-MM-DD')),
    nvl(col2,TO_DATE('2901-01-01','YYYY-MM-DD')),
    nvl(col3,TO_DATE('2901-01-01','YYYY-MM-DD')),
    nvl(col4,TO_DATE('2901-01-01','YYYY-MM-DD'))
    ) 
    = TO_DATE('2901-01-01','YYYY-MM-DD') 
then null 
else 
    least 
(
nvl(col1,TO_DATE('2901-01-01','YYYY-MM-DD')),
nvl(col2,TO_DATE('2901-01-01','YYYY-MM-DD')),
nvl(col3,TO_DATE('2901-01-01','YYYY-MM-DD')),
nvl(col4,TO_DATE('2901-01-01','YYYY-MM-DD'))
) 
end 
as min_date
from tbl

If you want the first date, then use coalesce() :

select coalesce(col1, col2, col3, col4)
from t;

This returns the first non- NULL value (which is one way that I interpret the question). This will be the minimum date, if the dates are in order.

Select Id, CaseWhen (Col1 <= Col2 OR Col2 is null) And (Col1 <= Col3 OR Col3 is null) Then Col1 When (Col2 <= Col1 OR Col1 is null) And (Col2 <= Col3 OR Col3 is null) Then Col2 Else Col3 End As Min From YourTable 

这适用于3列,用相同的方式可以编写4列或更多列。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM