2011-09-13 36 views
62

Tôi biết rằng nhiều thông số có thể được chuyển đến COALESCE, nhưng khi bạn muốn chỉ kiểm tra một biểu thức để xem nó có tồn tại hay không, bạn có sử dụng mặc định hay không hay sử dụng ISNULL thay thế?Sử dụng ISNULL và sử dụng COALESCE để kiểm tra một điều kiện cụ thể?

Có bất kỳ lợi ích nào về hiệu suất giữa hai loại này không?

+5

[COALESCE documentation] (http://msdn.microsoft.com/en-us/library/ms190349.aspx) có ghi chú này: ISNULL và COALESCE mặc dù tương đương, có thể hoạt động khác nhau. Một biểu thức liên quan đến ISNULL với các tham số không null được coi là NOT NULL, trong khi các biểu thức liên quan đến COALESCE với các tham số không null được coi là NULL ... –

+3

'ISNULL' cũng sẽ ép buộc kết quả cho kiểu dữ liệu của biểu thức đầu tiên [ như minh họa ở đây] (http://haacked.com/archive/2005/01/21/difference-between-isnull-and-coalesce.aspx) –

+4

Bài viết này nêu ra sự khác biệt khá tốt ... http: // sqlmag .com/t-sql/coalesce-vs-isnull –

Trả lời

47

This problem reported on Microsoft Connect tiết lộ một số khác biệt giữa COALESCEISNULL:

một phần không thể sớm xử lý của chúng tôi viết lại COALESCE(expression1, expression2) như CASE WHEN expression1 IS NOT NULL THEN expression1 ELSE expression2 END. Trong [ví dụ này]:

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

chúng ta tạo ra:

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

giai đoạn sau của xử lý truy vấn không hiểu rằng hai truy vấn phụ ban đầu cùng một biểu thức, vì vậy họ thực hiện subquery hai lần ..

Một giải pháp thay thế, mặc dù tôi không muốn đề xuất, thay đổi COALESCE thành ISNULL, vì sau này không trùng lặp truy vấn phụ.

+2

câu hỏi nhanh, nếu bạn có 3 giá trị, như coalesce (expression1, expression2, expression3, 1), trong đó những 'biểu thức' này thực sự chọn các câu lệnh, sau đó nó có ý nghĩa với các câu lệnh isnull lồng nhau không? tức là isnull (expression1, isnull (expression2, isnull (expression3, 1))) – ganders

22

Tôi nghĩ là không, nhưng COALESCE nằm trong tiêu chuẩn SQL '92 và được hỗ trợ bởi nhiều cơ sở dữ liệu khác nhau. Nếu bạn đi cho tính di động, không sử dụng ISNULL.

+2

là nó isnull của ifnull? –

+9

Điểm của tôi chính xác. ;-D Và đó là NVL trong Oracle. – GolezTrol

1

Trong trường hợp chỉ có một điều kiện rỗng, ISNULL sẽ có ít chi phí hơn. Sự khác biệt có lẽ là không đáng kể, mặc dù.

+1

Bạn có bất kỳ hỗ trợ nào cho tuyên bố rằng có ít chi phí hơn với 'ISNULL' không? –

+0

@JoshuaDrake: Có hai khu vực mà 'COALESCE' sẽ giới thiệu thêm chi phí khi sử dụng thay thế cho nhau. Đầu tiên, 'ISNULL' giao dịch với số lượng đầu vào cố định, trong đó' COALESCE' được chỉ định để hoạt động với bất kỳ số lượng đầu vào nào. Thứ hai, 'COALESCE' được cấu hình để trả về kiểu dữ liệu của biểu thức có ưu tiên kiểu dữ liệu cao nhất, trong khi' ISNULL' trả về cùng kiểu với 'check_expression'. Như tôi đã nói ở trên, trong các phiên bản sau của SQL Server sự khác biệt có lẽ là không đáng kể, nhưng nói đúng là vẫn còn trên cao. –

9

Trong COALESCE bạn có thể có nhiều biểu thức, nơi như trong ISNULL bạn có thể kiểm tra chỉ có một biểu hiện

COALESCE (expression [ ,...n ]) 

ISNULL (check_expression , replacement_value) 
-2

Trong liên hiệp người ta có thể sử dụng nhiều biểu thức, Nó sẽ trở lại giá trị mà không phải là một null và xảy ra đầu tiên ... ví dụ

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) 

và trong ISNULL nếu biểu null nó sẽ trở lại tham số thứ hai được cung cấp, và tất nhiên bạn có thể kiểm tra chỉ dành cho một biểu hiện ...

Vì vậy, nếu muốn kiểm tra nhiều biểu hiện và chọn đầu tiên không phải là null trong số đó, sau đó sử dụng liên hiệp nếu không đi cho ISNULL

+2

OP nói rằng họ đã nhận thức được khả năng của COALESCE để xử lý nhiều tham số, câu hỏi là về trường hợp cụ thể khi chỉ có hai. –

+0

@JoshuaDrake xin vui lòng đọc câu trả lời hoàn chỉnh ... Tôi đọc câu hỏi và tôi yêu cầu bạn đọc câu trả lời của tôi hoàn toàn ... Nó rất dễ dàng để xem xét một số điểm và xuống bỏ phiếu nó –

4

Đáng nói là việc xử lý loại giữa hai cũng có thể tạo sự khác biệt (xem this related answer item (2)).

Nói một truy vấn cố gắng sử dụng một phím tắt để viết so sánh null:

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

đó là khác biệt so với

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

Bởi vì trong trường hợp đầu tiên, IsNull() buộc kiểu được một chút (do đó -1 được chuyển thành true) trong khi trường hợp thứ hai sẽ thúc đẩy cả hai thành một 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; 

Có một nhận xét/liên kết tương tự (@Martin Smith) về chính câu hỏi đó.

4

Một điều quan trọng mà tôi không thấy rõ ràng chỉ ra rằng loại đầu ra của ISNULL tương tự như biểu thức đầu tiên nhưng với COALESCE nó trả về kiểu dữ liệu của giá trị ưu tiên cao nhất.

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ó không phải là vấn đề đầu tiên vs thứ hai/Nth biểu hiện. Xem [ở đây] (http://stackoverflow.com/questions/18828641/sql-difference-between-coalesce-and-isnull/18828687#18828687): 'ISNULL sử dụng kiểu dữ liệu của tham số đầu tiên, COALESCE tuân theo biểu thức CASE quy tắc và trả về kiểu dữ liệu của giá trị có mức ưu tiên cao nhất.' –

2

lời giải thích này mang lại cho rõ ràng về liên hiệp vs ISNULL

Chức năng liên hiệp trong SQL trả về biểu hiện không NULL đầu tiên giữa các đối số của nó. Cú pháp cho liên hiệp là như sau:

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

Nó là tương tự như câu lệnh CASE sau:

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"; 

Trong SQL Server, ISNULL() chức năng được sử dụng để thay thế giá trị NULL với giá trị khác .

Trả lại kết quả đầu tiên không rỗng khi mà isnull() được sử dụng để thay thế giá trị null bằng giá trị mong muốn của chúng tôi.

COALESCE là một phần của tiêu chuẩn ANSI và có sẵn trong hầu hết các cơ sở dữ liệu.

khi quyết định giữa ISNULL v liên hiệp có các thông số đã được đưa về chăm sóc off:

  1. liên hiệp xác định loại đầu ra dựa trên kiểu dữ liệu được ưu tiên nơi như Với ISNULL, các kiểu dữ liệu không bị ảnh hưởng bởi dữ liệu loại ưu tiên.
  2. xem xét sau báo cáo sql

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

Kết quả:

COALESCE longer name 
ISNULL longe 

Điều này xảy ra bởi vì ISNULL mất kiểu dữ liệu của đối số đầu tiên, trong khi liên hiệp kiểm tra tất cả các yếu tố và chọn phù hợp nhất (trong trường hợp này, VARCHAR (11))

Để được giải thích chi tiết hơn về decidin g giữa COALESCE và ISNULL hãy kiểm tra điều này: https://www.mssqltips.com/sqlservertip/2689/deciding-between-coalesce-and-isnull-in-sql-server/

0

NULLCOALESCE không phải lúc nào cũng có thể hoán đổi cho nhau. Nó xứng đáng để biết sự khác biệt của họ để biết được khi nào nó tốt hơn để sử dụng một trong khác:

enter image description here

Bảng trên là so sánh giữa ISNULLCOALESCE từ Exam Ref 70-761 Querying Data with Transact-SQL cuốn sách được viết bởi Itzik Ben-Gan.


  1. Số thông số được hỗ trợ - 2 cho ISNULL vs >2 khi sử dụng COALESCE
  2. ISNULL là tính năng độc quyền của T-SQL và COALESCE là ISO/ANSI SQL chuẩn
  3. Các kiểu dữ liệu của kết quả là quan trọng. Sau khi đọc các ghi chú trong bảng trên, kiểm tra các trường hợp sau:

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

    enter image description here

    Các ISNULL là nhận được kiểu dữ liệu của đối số đầu tiên vì nó là không NULL chữ. Nó là VARCHAR(3) và là kết quả, dữ liệu đối số thứ hai được cắt để khớp với nó. Với COALESCE loại dữ liệu nếu ưu tiên cao nhất là được sử dụng.

    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

    Các ISNULL đang trở lại kiểu dữ liệu của đối số đầu tiên, trong khi ở COALESCE chúng tôi đang nhận lỗi, như INT có độ ưu tiên cao nhất và chuyển đổi những người đầu tiên giá trị đối số đến INT không thành công.

  4. Khả năng vô hiệu của kết quả cũng quan trọng. Đối với, ví dụ:

    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]; 
    

    Hãy kiểm tra các Nullable tài sản của mỗi cột:

    enter image description here

    enter image description here

    Sử dụng COALESCE chúng tôi có một tài sản của cột thiết lập để YesNOT NULL, chỉ khi tất cả các đầu vào đều không có khả năng.

  5. Theo tiêu chuẩn SQL, khái niệm COALESCE được phiên dịch sang:

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

    Nếu kết quả của việc thực hiện các subquery trong mệnh đề KHI không phải là NULL, SQL Server thực hiện nó lần thứ hai trong mệnh đề THEN. Nói cách khác, trong trường hợp này nó thực hiện nó hai lần. Chỉ khi kết quả của việc thực hiện trong mệnh đề WHEN là NULL, SQL Server không thi hành lại truy vấn phụ, thay vì trả về biểu thức ELSE. Vì vậy, khi sử dụng truy vấn con, hàm ISNULL có lợi thế hiệu suất .

Các vấn đề liên quan