簡體   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