我有一张像这样的桌子
ID Col1 Col2 Col3
-- ---- ---- ----
1 7 NULL 12
2 2 46 NULL
3 NULL NULL NULL
4 245 1 792
我想要一个产生以下结果的查询
ID Col1 Col2 Col3 MIN
-- ---- ---- ---- ---
1 7 NULL 12 7
2 2 46 NULL 2
3 NULL NULL NULL NULL
4 245 1 792 1
我的意思是,我想要一个包含Col1,Col2和Col 3中最小值的列,每行忽略NULL值。在上一个问题(What's the best way to select the minimum value from multiple columns?)中,有一个非NULL值的答案。我需要一个查询尽可能高效的表格。
Select Id,
Case When Col1 < Col2 And Col1 < Col3 Then Col1
When Col2 < Col1 And Col2 < Col3 Then Col2
Else Col3
End As MIN
From YourTableNameHere
答案 0 :(得分:3)
假设您可以定义一些&#34; max&#34;价值(我在这里使用9999)你的真实价值永远不会超过:
Select Id,
Case When Col1 < COALESCE(Col2, 9999)
And Col1 < COALESCE(Col3, 9999) Then Col1
When Col2 < COALESCE(Col1, 9999)
And Col2 < COALESCE(Col3, 9999) Then Col2
Else Col3
End As MIN
From YourTableNameHere;
答案 1 :(得分:0)
这可能有效:
Select id, Col1, Col2, Col3, least(Col1, Col2, Col3) as MIN From YourTableNameHere
答案 2 :(得分:0)
您没有指定您正在使用的Teradata版本。如果您使用的是版本14+,则可以使用least
。
不幸的是,least
如果其任何参数为null,则返回null。来自文档:
LEAST支持1-10个数值。 如果numeric_value是第一个参数的数据类型,则返回 数据类型是数字。输入列表中的其余参数必须 是相同或兼容的类型。如果任一输入参数为NULL, 返回NULL。
但是你可以通过使用coalesce
来解决这个问题,就像Joe在答案中所做的那样。
select id,
least(coalesce(col1,9999),coalesce(col2,9999),coalesce(col3,9999))
from mytable
答案 3 :(得分:0)
这样您就不需要检查nulls
,只需使用min
和subquery
select tbl.id,tbl.col1,tbl.col2,tbl.col3,
(select min(t.col)
from (
select col1 as col from tbl_name t where t.id=tbl.id
union all
select col2 as col from tbl_name t where t.id=tbl.id
union all
select col3 as col from tbl_name t where t.id=tbl.id
)t)
from tbl_name tbl
输出:
1 7 NULL 12 7
2 2 46 NULL 2
3 NULL NULL NULL NULL
4 245 1 792 1
答案 4 :(得分:0)
只需使用coalesce()
修改您的查询:
Select Id,
(Case When Col1 <= coalesce(Col2, col3, col1) And
Col1 <= coalesce(Col3, col2, col1)
Then Col1
When Col2 <= coalesce(Col1, col3, col2) And
Col2 <= coalesce(Col3, col1, col2)
Then Col2
Else Col3
End) As MIN
From YourTableNameHere;
这不需要发明“魔术”数字或过度复杂的逻辑。
答案 5 :(得分:0)
我发现这个解决方案比使用多个case语句更有效,在评估一行中多个列的数据时,这些子句会非常冗长。
此外,我不能赞同这个解决方案,因为我在大约一年前的某个网站上发现了这个解决方案。今天我需要刷新这个逻辑,我无法在任何地方找到它。我发现了我的旧代码,现在决定在这个论坛上分享它。
创建测试表:
create table #testTable(ID int, Col1 int, Col2 int, Col3 int)
Insert into #testTable values(1,7,null,12)
Insert into #testTable values(2,2,46,null)
Insert into #testTable values(3,null,null,null)
Insert into #testTable values(4,245,1,792)
在行数据中查找最小值:
Select ID, Col1, Col2, Col3 ,(SELECT Min(v) FROM ( VALUES (Col1), (Col2), (Col3) ) AS value(v)) [MIN] from #testTable order by ID