Thay thế NULL bằng 0 trong truy vấn máy chủ SQL


175

Tôi đã phát triển một truy vấn và trong các kết quả cho ba cột đầu tiên tôi nhận được NULL. Làm thế nào tôi có thể thay thế nó bằng 0?

  Select c.rundate, 
    sum(case when c.runstatus = 'Succeeded' then 1 end) as Succeeded, 
    sum(case when c.runstatus = 'Failed' then 1 end) as Failed, 
    sum(case when c.runstatus = 'Cancelled' then 1 end) as Cancelled, 
    count(*) as Totalrun from
    (    Select a.name,case when b.run_status=0 Then 'Failed' when b.run_status=1 Then 'Succeeded'
    when b.run_status=2 Then 'Retry' Else 'Cancelled' End as Runstatus,
    ---cast(run_date as datetime)
                cast(substring(convert(varchar(8),run_date),1,4)+'/'+substring(convert(varchar(8),run_date),5,2)+'/'          +substring(convert(varchar(8),run_date),7,2) as Datetime) as RunDate
    from msdb.dbo.sysjobs as a(nolock) inner join msdb.dbo.sysjobhistory as b(nolock) 
    on a.job_id=b.job_id
    where a.name='AI'
    and b.step_id=0) as c
    group by 
    c.rundate

@ user2246674 Ba cột đầu tiên: sum (trường hợp khi c.runstatus = 'Thành công' rồi 1 kết thúc) là Thành công, tổng (trường hợp khi c.runstatus = 'Thất bại' rồi 1 kết thúc) là Thất bại, tổng (trường hợp khi c.runstatus = 'Đã hủy' rồi 1 kết thúc) là Đã hủy
Bhaskar Mishra

Sparky, Oracle không khác biệt khi sử dụng NVL hoặc NVL2 ... kiểm tra oracle-base.com/articles/misc/null-related-fifts
KingRider

Câu trả lời:


376

Khi bạn muốn thay thế một nullcột có thể bằng một cái gì đó khác, hãy sử dụng IsNull .

SELECT ISNULL(myColumn, 0 ) FROM myTable

Điều này sẽ đặt 0 trong myColumn nếu nó là null ở vị trí đầu tiên.


2
Đối với những người sử dụng SQL Server 2000 hoặc 2005 ISNULL là SQL Server 2008 trở lên.
Kyle

1
đối với nhiều cột tôi có phải viết ISNULL nhiều lần hay có thứ gì đó giống như ISNULL (myColumns, 0) không?
Flaudre

@Kyle: Điều đó không chính xác: Từ kinh nghiệm cá nhân (và trích dẫn sách ), tôi có thể xác nhận rằng ISNULL được hỗ trợ vì (ít nhất là) SQL Server 2000, thậm chí có thể sớm hơn.
Heinzi

@Flaudre: Bạn phải viết ISNULL nhiều lần, vì mỗi cột đầu ra phải có biểu thức riêng.
Heinzi

Điều này cũng giúp tôi có được kết quả chính xác trong SQL Server 2016. Cảm ơn rất nhiều, bạn vừa thực hiện một ngày của tôi @phadaphunk
PatsonLeaner

83

Bạn có thể sử dụng cả hai phương pháp này nhưng có những khác biệt:

SELECT ISNULL(col1, 0 ) FROM table1
SELECT COALESCE(col1, 0 ) FROM table1

So sánh COALESCE () và ISNULL ():

  1. Hàm ISNULL và biểu thức COALESCE có cùng mục đích nhưng có thể hoạt động khác nhau.

  2. Vì ISNULL là một hàm, nó chỉ được đánh giá một lần. Như được mô tả ở trên, các giá trị đầu vào cho biểu thức COALESCE có thể được đánh giá nhiều lần.

  3. Xác định kiểu dữ liệu của biểu thức kết quả là khác nhau. ISNULL sử dụng kiểu dữ liệu của tham số đầu tiên, COALESCE tuân theo các quy tắc biểu thức CASE và trả về loại dữ liệu có giá trị với mức ưu tiên cao nhất.

  4. Khả năng NULL của biểu thức kết quả là khác nhau đối với ISNULL và COALESCE. Giá trị trả về ISNULL luôn được coi là KHÔNG NULL (giả sử giá trị trả về là không có giá trị) trong khi COALESCE với các tham số không null được coi là NULL. Vì vậy, các biểu thức ISNULL (NULL, 1) và COALESCE (NULL, 1) mặc dù tương đương có các giá trị vô hiệu khác nhau. Điều này tạo ra sự khác biệt nếu bạn đang sử dụng các biểu thức này trong các cột được tính toán, tạo các ràng buộc chính hoặc làm cho giá trị trả về của một định nghĩa UDF vô hướng để nó có thể được lập chỉ mục như trong ví dụ sau.

- Tuyên bố này không thành công vì KEY PRIMARY không thể chấp nhận các giá trị NULL - và tính vô hiệu của biểu thức COALESCE cho col2 - ước tính thành NULL.

CREATE TABLE #Demo 
( 
    col1 integer NULL, 
    col2 AS COALESCE(col1, 0) PRIMARY KEY, 
    col3 AS ISNULL(col1, 0) 
); 

- Tuyên bố này thành công vì tính vô hiệu của hàm - ISNULL đánh giá NHƯ KHÔNG PHẢI.

CREATE TABLE #Demo 
( 
    col1 integer NULL, 
    col2 AS COALESCE(col1, 0), 
    col3 AS ISNULL(col1, 0) PRIMARY KEY 
);
  1. Xác nhận cho ISNULL và COALESCE cũng khác nhau. Ví dụ: giá trị NULL cho ISNULL được chuyển đổi thành int trong khi đối với COALESCE, bạn phải cung cấp loại dữ liệu.

  2. ISNULL chỉ mất 2 tham số trong khi COALESCE có số lượng tham số thay đổi.

    nếu bạn cần biết thêm ở đây là tài liệu đầy đủ từ msdn.


23

Với coalesce:

coalesce(column_name,0)

Mặc dù, khi tổng kết when condition then 1, bạn có thể dễ dàng thay đổi sumthành count- ví dụ:

count(case when c.runstatus = 'Succeeded' then 1 end) as Succeeded,

( Count(null)trả về 0, trong khi sum(null)trả về null.)


10

Khi bạn nói ba cột đầu tiên, bạn có nghĩa là các SUMcột của bạn ? Nếu vậy, thêm ELSE 0vào CASEbáo cáo của bạn . Các SUMcủa một NULLgiá trị NULL.

sum(case when c.runstatus = 'Succeeded' then 1 else 0 end) as Succeeded, 
sum(case when c.runstatus = 'Failed' then 1 else 0 end) as Failed, 
sum(case when c.runstatus = 'Cancelled' then 1 else 0 end) as Cancelled, 

8

Một cách đơn giản là

UPDATE tbl_name SET fild_name = value WHERE fild_name IS NULL

7

Bọc cột của bạn trong mã này.

 ISNULL(Yourcolumn, 0)

Có thể kiểm tra lý do tại sao bạn nhận được null


6

Sử dụng COALESCE, trả về giá trị không null đầu tiên, vd

SELECT COALESCE(sum(case when c.runstatus = 'Succeeded' then 1 end), 0) as Succeeded

Sẽ đặt Thành công là 0 nếu được trả về là NULL.


1

Thêm một cái khác vào các câu lệnh tình huống của bạn để chúng mặc định là 0 nếu không tìm thấy điều kiện kiểm tra. Hiện tại, nếu điều kiện kiểm tra không tìm thấy NULL đang được chuyển đến hàm SUM ().

  Select c.rundate, 
    sum(case when c.runstatus = 'Succeeded' then 1 else 0 end) as Succeeded, 
    sum(case when c.runstatus = 'Failed' then 1 else 0 end) as Failed, 
    sum(case when c.runstatus = 'Cancelled' then 1 else 0 end) as Cancelled, 
    count(*) as Totalrun from
    (    Select a.name,case when b.run_status=0 Then 'Failed' when b.run_status=1 Then 'Succeeded'
    when b.run_status=2 Then 'Retry' Else 'Cancelled' End as Runstatus,
    ---cast(run_date as datetime)
                cast(substring(convert(varchar(8),run_date),1,4)+'/'+substring(convert(varchar(8),run_date),5,2)+'/'          +substring(convert(varchar(8),run_date),7,2) as Datetime) as RunDate
    from msdb.dbo.sysjobs as a(nolock) inner join msdb.dbo.sysjobhistory as b(nolock) 
    on a.job_id=b.job_id
    where a.name='AI'
    and b.step_id=0) as c
    group by 
    c.rundate

1

Nếu bạn đang sử dụng Presto, AWS Athena, v.v., không có chức năng ISNULL (). Thay vào đó, sử dụng:

SELECT COALESCE(myColumn, 0 ) FROM myTable

0
sum(case when c.runstatus = 'Succeeded' then 1 else 0 end) as Succeeded, 
sum(case when c.runstatus = 'Failed' then 1 else 0 end) as Failed, 
sum(case when c.runstatus = 'Cancelled' then 1 else 0 end) as Cancelled, 

vấn đề ở đây là không có câu lệnh khác, bạn buộc phải nhận Null khi trạng thái chạy không phải là trạng thái đã nêu trong mô tả cột. Thêm bất cứ điều gì vào Null sẽ dẫn đến Null và đó là vấn đề với truy vấn này.

Chúc may mắn!


0

bằng cách làm theo các câu trả lời trước, tôi đã mất tên cột của mình trong máy chủ SQL db, tuy nhiên theo cú pháp này cũng giúp tôi giữ lại Tên cột

ISNULL(MyColumnName, 0) MyColumnName
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.