2011-09-13 33 views
62

我知道可以將多個參數傳遞給COALESCE,但是當您想要 時只檢查一個表達式以查看它是否不存在,您使用默認值還是更好地使用ISNULL來代替?使用ISNULL vs使用COALESCE來檢查特定條件?

兩者之間是否有任何性能提升?

+5

的[COALESCE文檔】(http://msdn.microsoft。com/en-us/library/ms190349.aspx)有這樣的註釋:ISNULL和COALESCE雖然相同,但可以有不同的表現。涉及帶有非空參數的ISNULL的表達式被認爲是NOT NULL,而涉及具有非空參數的COALESCE的表達式被認爲是NULL ... – 2011-09-13 21:44:44

+3

'ISNULL'也將強制結果爲第一個表達式的數據類型[如圖所示](http://haacked.com/archive/2005/01/21/difference-between-isnull-and-coalesce.aspx) –

+4

本文詳細說明了這些差異... http:// sqlmag .com/t-sql/coalesce-vs-isnull –

回答

47

This problem reported on Microsoft Connect揭示COALESCEISNULL之間存在一些差異:

我們處理的早期部分重寫COALESCE(expression1, expression2)CASE WHEN expression1 IS NOT NULL THEN expression1 ELSE expression2 END。在[這個例子]:

COALESCE ((SELECT Nullable 
      FROM Demo 
      WHERE SomeCol = 1), 1) 

我們產生:查詢處理的

SELECT CASE 
      WHEN (SELECT Nullable FROM Demo WHERE SomeCol = 1) IS NOT NULL 
      THEN (SELECT Nullable FROM Demo WHERE SomeCol = 1) 
      ELSE 1 
     END 

後期階段不明白的是,兩個子查詢原本相同的表情,讓他們執行子查詢兩次..

一種解決方法,儘管我討厭建議它,但將COALESCE更改爲ISNULL,因爲後者不會重複子查詢。

+2

快速的問題,如果你有3個值,如coalesce(expression1,expression2,expression3,1),其中'表達式'實際上是選擇語句,那麼它會對實際做嵌套的isnull語句有意義嗎?即isnull(表達式1,isnull(表達式2,isnull(表達式3,1))) – ganders

22

我認爲不是,但COALESCE是在SQL '92標準,並支持更多不同的數據庫。如果你爲了便攜而去,不要使用ISNULL。

+2

它是否爲空? –

+9

我的觀點正好。 ;-D它是Oracle中的NVL。 – GolezTrol

1

凡只有一個空條件,ISNULL將有較少的開銷。不過,這個差別可能是微不足道的。

+1

您是否有支持'ISNULL'開銷較少的說法? –

+0

@JoshuaDrake:有兩個地方可以互換使用'COALESCE'會引入更多的開銷。首先,「ISNULL」處理固定數量的輸入,其中「COALESCE」被指定爲與任意數量的輸入一起工作。其次,'COALESCE'配置爲返回具有最高數據類型優先級的表達式的數據類型,而'ISNULL'返回與'check_expression'相同的類型。正如我上面所說的,在更高版本的SQL Server中,差異可能可以忽略不計,但嚴格來說,仍然存在開銷。 –

9

COALESCE你可以有多種表現形式,其中在ISNULL可以檢查只有一個表達式

COALESCE (expression [ ,...n ]) 

ISNULL (check_expression , replacement_value) 
-2

在COALESCE可以使用多個表達式,它會返回值是不是空和發生第一...例如

DECLARE @Value1 INT, @Value2 INT, @Value3 INT, @Value4 INT 
SELECT @Value2 = 2, @Value4 = 4 
SELECT COALESCE(@Value1, @Value2, @Value3, @Value4) 
SELECT COALESCE(@Value1, @Value4, @Value3, @Value2) 

而且在ISNULL如果表達式爲null,則返回第二個參數提供的,當然你可以只檢查一個表達...

所以,如果要檢查多個表達式,選擇其中首先不爲空,然後用凝聚否則去ISNULL

+2

OP表示他們意識到COALESCE處理多個參數的能力,問題是關於只有兩個參數的具體情況。 –

+0

@JoshuaDrake請閱讀完整答案...我讀了一個問題,我要求你完全閱讀我的答案......它很容易結束看點和投票 –

4

值得一提的是,兩者之間的類型處理也可以有所作爲(見this related answer item (2))。

說查詢試圖使用快捷方式寫入零比較:

select * from SomeTable 
where IsNull(SomeNullableBitField, -1) != IsNull(SomeOtherNullableBitField, -1); 

其中因爲在第一種情況下比

select * from SomeTable 
where coalesce(SomeNullableBitField, -1) != coalesce(SomeOtherNullableBitField, -1); 

不同,則ISNULL()強制類型爲有一點(所以-1被轉換爲真),而第二種情況將促進兩個int。

with input as 
(
    select convert(bit, 1) as BitOn,  
     convert(bit, 0) as BitOff, 
     convert(bit, null) as BitNull 
) 
select BitOn, 
     BitOff, 
     BitNull, 
     IsNull(BitOn, -1) IsNullBitOn,   -- true 
     IsNull(BitOff, -1) IsNullBitOff,  -- false 
     IsNull(BitNull, -1) IsNullBitNull,  -- true, converts the -1 to bit 
     coalesce(BitOn, -1) CoalesceBitOn,  -- 1 
     coalesce(BitOff, -1) CoalesceBitOff, -- 0  
     coalesce(BitNull, -1) CoalesceBitNull -- -1 
    from input; 

對問題本身有類似的評論/鏈接(@Martin Smith)。

4

我沒有看到明確指出的一個主要問題是ISNULL的輸出類型與第一個表達式類似,但COALESCE它返回最高優先級值的數據類型。

DECLARE @X VARCHAR(3) = NULL 
DECLARE @Y VARCHAR(10) = '123456789' 
/* The datatype returned is similar to X, or the first expression*/ 
SELECT ISNULL(@X, @Y) ---> Output is '123' 
/* The datatype returned is similar to Y, or to the value of highest precedence*/ 
SELECT COALESCE(@X, @Y) ---> Output is '123456789' 
+3

這不是第一和第二/第N表達式的問題。見[這裏](http://stackoverflow.com/questions/18828641/sql-difference-between-coalesce-and-isnull/18828687#18828687):'ISNULL使用第一個參數的數據類型,COALESCE遵循CASE表達式規則並返回具有最高優先級的值的數據類型 –

2

這一解釋提供了明確的關於聚結VS ISNULL

在SQL函數COALESCE返回它的參數中的第一個非空表達式。對於聚結語法如下:

COALESCE ("expression 1", "expressions 2", ...) 

它一樣以下CASE語句:

SELECT CASE ("column_name") 
    WHEN "expression 1 is not NULL" THEN "expression 1" 
    WHEN "expression 2 is not NULL" THEN "expression 2" 
    ... 
    [ELSE "NULL"] 
    END 
FROM "table_name"; 

在SQL Server中,ISNULL()函數用於與另一個值替換NULL值。

select CountryName = ISNULL("columnname", 'INDIA') from Countries 

合併返回第一個非空表達式,其中asnull()用於用我們期望的值替換空值。

COALESCE是ANSI標準的一部分,幾乎可用於所有數據庫。

ISNULL v COALESCE之間決定有參數時

必須照顧關:

  1. COALESCE確定基於數據類型的優先級的輸出的類型,其中,與ISNULL,數據類型不是由數據的影響鍵入優先級。
  2. 考慮以下SQL語句

    DECLARE @c5 VARCHAR(5); 
    SELECT 'COALESCE', COALESCE(@c5, 'longer name') 
    UNION ALL 
    SELECT 'ISNULL', ISNULL(@c5, 'longer name'); 
    

結果:

COALESCE longer name 
ISNULL longe 

這是因爲ISNULL取第一參數的數據類型,而COALESCE檢查所有元素,並選擇最適合(在這種情況下,VARCHAR(11))

有關decidin的更多詳細說明g COALESCE vs ISNULL檢查此: https://www.mssqltips.com/sqlservertip/2689/deciding-between-coalesce-and-isnull-in-sql-server/

0

NULLCOALESCE並不總是可以互換的。它有權知道他們之間的分歧,以便知道什麼時候它能夠更好地使用了另一種:

enter image description here

上面的表格是由伊茨克奔甘書面Exam Ref 70-761 Querying Data with Transact-SQLISNULLCOALESCE之間的比較。


  1. 支持的參數的數 - 2ISNULL VS >2使用COALESCE
  2. ISNULL時是專有的T-SQL特徵和COALESCE是ISO/ANSI SQL標準
  3. 結果的數據類型很重要。上表中的讀書筆記後,檢查以下情況:

    DECLARE @x VARCHAR(3) = NULL 
         ,@y VARCHAR(10) = '1234567890'; 
    
    SELECT ISNULL(@x, @y) AS [ISNULL], COALESCE(@x, @y) AS [COALESCE]; 
    

    enter image description here

    ISNULL越來越第一個參數的數據類型,因爲它是不 NULL文字。這是VARCHAR(3),結果,第二個參數數據 被剪切以匹配它。如果使用COALESCE,則數據類型(如果最高優先級爲 )。

    DECLARE @x VARCHAR(8) = '123x5' 
         ,@y INT = 123; 
    
    SELECT ISNULL(@x, @y) AS [ISNULL]; 
    SELECT COALESCE(@x, @y) AS [COALESCE]; 
    

    enter image description here

    enter image description here

    ISNULL將返回第一個參數的數據類型,而在 COALESCE我們得到的錯誤,因爲INT具有最高的優先級和 轉換第一參數值爲INT失敗。

  4. 結果的可空性也很重要。對於,例如:

    DECLARE @x VARCHAR(3) = NULL 
         ,@y VARCHAR(3) = NULL; 
    
    DROP TABLE IF EXISTS [dbo].[DataSource01]; 
    
    SELECT ISNULL(10, 20) AS [C1] 
         ,ISNULL(@x, 'text') AS [C2] 
         ,ISNULL(@x, @y) AS [C3] 
    INTO [dbo].[DataSource01]; 
    
    DROP TABLE IF EXISTS [dbo].[DataSource02]; 
    
    SELECT COALESCE(10, 20) AS [C1] 
         ,COALESCE(@x, 'text') AS [C2] 
         ,COALESCE(@x, @y) AS [C3] 
    INTO [dbo].[DataSource02]; 
    

    讓我們來看看每列的Nullable屬性:

    enter image description here

    enter image description here

    使用COALESCE我們必須設置爲Yes列的NOT NULL財產,只有 當所有的輸入都是不可空的。

  5. 根據SQL標準,在COALESCE表達被翻譯成:

    CASE WHEN (<subquery>) IS NOT NULL THEN (<subquery>) ELSE 0 END 
    

    如果子查詢的WHEN子句中的執行結果並不 NULL,SQL Server執行它在THEN子句中第二次。換句話說,在這種情況下,它執行兩次。只有在WHEN子句中執行的結果爲 爲NULL時,SQL Server纔不會再次 執行子查詢,而是返回ELSE表達式。所以當使用子查詢時,因爲 ,ISNULL函數具有性能 的優勢。