如何从 SQL 中的一行的多个列中获取最小值
How to get min value from multiple columns for a row in SQL
我需要从一组 4(或更多)列中获取第一个(最小)日期。
我试过了
select 来自 tbl
的最小值 (col1, col2, col3)
这显然是错误的。
假设我有这 4 列
col1 | col2 | col3 | col4
1/1/17 | 2/2/17 | | 3/3/17
... 在这种情况下,我想要获得的是 col1 (1/1/17) 中的值。是的,这些列可以包含 NULL。
我是 运行 dashDB 中的这个
列是日期数据类型,
此 table、
中既没有 ID 也没有主键列
我需要对查询中的所有行执行此操作,
列顺序不对。这意味着 col1 不必在 col2 之前或者它必须为空并且 col2 不必在 col3 之前或者它必须为 NULL ..等等
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 列或更多列。
如果您的 table 中有一个 id
列。那么
查询
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;
如果你想要第一个日期,那么使用coalesce()
:
select coalesce(col1, col2, col3, col4)
from t;
这是第一个 returns 非 NULL
值(这是我解释问题的一种方式)。如果日期是有序的,这将是最短日期。
如果你的数据库支持最少的功能,这是最好的方法
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
编辑:如果所有列都为空,那么您可以将输出硬编码为 null
。以下查询应该有效。我无法测试它,但这应该有效。
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
我需要从一组 4(或更多)列中获取第一个(最小)日期。
我试过了
select 来自 tbl
的最小值 (col1, col2, col3)这显然是错误的。
假设我有这 4 列
col1 | col2 | col3 | col4
1/1/17 | 2/2/17 | | 3/3/17
... 在这种情况下,我想要获得的是 col1 (1/1/17) 中的值。是的,这些列可以包含 NULL。
我是 运行 dashDB 中的这个
列是日期数据类型,
此 table、
中既没有 ID 也没有主键列我需要对查询中的所有行执行此操作,
列顺序不对。这意味着 col1 不必在 col2 之前或者它必须为空并且 col2 不必在 col3 之前或者它必须为 NULL ..等等
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 列或更多列。
如果您的 table 中有一个 id
列。那么
查询
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;
如果你想要第一个日期,那么使用coalesce()
:
select coalesce(col1, col2, col3, col4)
from t;
这是第一个 returns 非 NULL
值(这是我解释问题的一种方式)。如果日期是有序的,这将是最短日期。
如果你的数据库支持最少的功能,这是最好的方法
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
编辑:如果所有列都为空,那么您可以将输出硬编码为 null
。以下查询应该有效。我无法测试它,但这应该有效。
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