繁体   English   中英

SQL:从多个具有空值的列中选择最小值

[英]SQL: Select the minimum value from multiple columns with null values

我有一张这样的桌子

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值。 在上一个问题( 从多列中选择最小值的最佳方法是什么? )中,有一个非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

假设您可以定义一些“最大”值(在这里我将使用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;

这可能起作用:

Select id, Col1, Col2, Col3, least(Col1, Col2, Col3) as MIN From YourTableNameHere

您没有指定要使用的Teradata版本。 如果您使用的是14+版本,则可以least使用。

不幸的是,如果其任何参数为null,则least返回null。 从文档:

最少支持1-10个数值。 如果numeric_value是第一个参数的数据类型,则返回数据类型是数字。 输入列表中的其余参数必须是相同或兼容的类型。 如果任一输入参数为NULL,则返回NULL。

但是您可以像乔在回答中那样使用coalesce来解决此问题。

select id, 
  least(coalesce(col1,9999),coalesce(col2,9999),coalesce(col3,9999))
from mytable

这样,您无需检查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

只需使用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;

这不需要发明一个“魔术”数或使逻辑过于复杂。

我发现此解决方案比使用多个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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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