การแทนที่ NULL ด้วย 0 ในเคียวรีเซิร์ฟเวอร์ SQL


175

NULLผมได้พัฒนาแบบสอบถามและในผลสำหรับสามคอลัมน์แรกที่ผมได้รับ ฉันจะแทนที่ด้วยได้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 สามคอลัมน์แรก: ผลรวม (ตัวพิมพ์ใหญ่เมื่อ c.runstatus = 'สำเร็จ' แล้ว 1 ปลาย) ตามความสำเร็จ, ผลรวม (ตัวพิมพ์ใหญ่เมื่อ c.runstatus = 'ล้มเหลว' จากนั้น 1 ปลาย) เป็นล้มเหลว, ผลรวม (กรณีเมื่อ c.runstatus = 'ยกเลิก' แล้ว 1 สิ้นสุด) ตามที่ถูกยกเลิก
Bhaskar Mishra

สปาร์กออราเคิลมีความแตกต่างจากการใช้ NVL หรือ NVL2 ... ตรวจสอบoracle-base.com/articles/misc/null-related-functions
KingRider

คำตอบ:


376

เมื่อคุณต้องการแทนที่อาจจะเป็นnullคอลัมน์ที่มีอย่างอื่นใช้IsNull

SELECT ISNULL(myColumn, 0 ) FROM myTable

สิ่งนี้จะใส่ 0 ใน myColumn ถ้ามันเป็นโมฆะในสถานที่แรก


2
สำหรับผู้ใช้น้อยที่ใช้ SQL Server 2000 หรือ 2005 ISNULL คือ SQL Server 2008 และสูงกว่า
Kyle

1
สำหรับหลายคอลัมน์ฉันต้องเขียน ISNULL หลายครั้งหรือมีบางอย่างที่เหมือน ISNULL (myColumns, 0)?
Flaudre

@ Kyle: ไม่ถูกต้อง: จากประสบการณ์ส่วนตัว (และใบเสนอราคาหนังสือ ) ฉันสามารถยืนยันได้ว่า ISNULL ได้รับการสนับสนุนตั้งแต่ (อย่างน้อย) SQL Server 2000 หรือแม้แต่ก่อนหน้านี้
Heinzi

@Flaudre: คุณต้องเขียน ISNULL หลายครั้งเนื่องจากทุกคอลัมน์ผลลัพธ์ต้องมีนิพจน์ของตัวเอง
Heinzi

สิ่งนี้ช่วยฉันได้เช่นกันเพื่อให้ได้ผลลัพธ์ที่ถูกต้องใน SQL Server 2016 ขอบคุณมากคุณเพิ่งทำวันของฉันที่ @phadaphunk
PatsonLeaner

83

คุณสามารถใช้ทั้งสองวิธีนี้ แต่มีความแตกต่าง:

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

เปรียบเทียบ COALESCE () และ ISNULL ():

  1. ฟังก์ชัน ISNULL และนิพจน์ COALESCE มีวัตถุประสงค์ที่คล้ายกัน แต่สามารถทำงานแตกต่างกันได้

  2. เนื่องจาก ISNULL เป็นฟังก์ชันจึงถูกประเมินเพียงครั้งเดียว ตามที่อธิบายไว้ข้างต้นค่าอินพุตสำหรับนิพจน์ COALESCE สามารถประเมินได้หลายครั้ง

  3. การกำหนดชนิดข้อมูลของนิพจน์ผลลัพธ์นั้นแตกต่างกัน ISNULL ใช้ชนิดข้อมูลของพารามิเตอร์แรก COALESCE ปฏิบัติตามกฎการแสดงออกของ CASE และส่งกลับค่าชนิดข้อมูลที่มีลำดับความสำคัญสูงสุด

  4. ความเป็น NULLability ของการแสดงออกของผลลัพธ์นั้นแตกต่างกันสำหรับ ISNULL และ COALESCE ค่าส่งคืน ISNULL ถูกพิจารณาว่าเป็นค่า NULLable เสมอ (สมมติว่าค่าส่งคืนเป็นค่าที่ไม่เป็นโมฆะ) ในขณะที่ COALESCE พร้อมพารามิเตอร์ที่ไม่ใช่ค่า Null ถือว่าเป็นค่า NULL ดังนั้นนิพจน์ ISNULL (NULL, 1) และ COALESCE (NULL, 1) ถึงแม้ว่าเทียบเท่าจะมีค่า null ที่แตกต่างกัน สิ่งนี้สร้างความแตกต่างถ้าคุณใช้นิพจน์เหล่านี้ในคอลัมน์ที่คำนวณสร้างข้อ จำกัด ที่สำคัญหรือสร้างค่าส่งคืนของ UDF สเกลาร์กำหนดเพื่อให้สามารถทำดัชนีตามที่แสดงในตัวอย่างต่อไปนี้

- คำสั่งนี้ล้มเหลวเนื่องจากคีย์หลักไม่สามารถยอมรับค่า NULL - และความสามารถในการลบล้างของนิพจน์ COALESCE สำหรับ col2 - ประเมินเป็น NULL

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

- คำสั่งนี้ประสบความสำเร็จเนื่องจากความสามารถในการลบล้างของ - ฟังก์ชั่น ISNULL จะประเมินเป็นไม่เป็นโมฆะ

CREATE TABLE #Demo 
( 
    col1 integer NULL, 
    col2 AS COALESCE(col1, 0), 
    col3 AS ISNULL(col1, 0) PRIMARY KEY 
);
  1. การตรวจสอบสำหรับ ISNULL และ COALESCE นั้นแตกต่างกัน ตัวอย่างเช่นค่า NULL สำหรับ ISNULL จะถูกแปลงเป็น int ในขณะที่สำหรับ COALESCE คุณต้องระบุชนิดข้อมูล

  2. ISNULL ใช้เวลาเพียง 2 พารามิเตอร์ในขณะที่ COALESCE รับจำนวนตัวแปร

    หากคุณต้องการทราบข้อมูลเพิ่มเติมที่นี่เป็นเอกสารฉบับเต็มจาก msdn


23

ด้วยcoalesce:

coalesce(column_name,0)

แม้ว่าที่ข้อสรุปwhen condition then 1คุณสามารถเปลี่ยนsumเป็นcount- เช่น:

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

( Count(null)คืนค่า 0 ขณะที่sum(null)ส่งคืนค่า null)


10

เมื่อคุณพูดสามคอลัมน์แรกคุณหมายถึงSUMคอลัมน์ของคุณหรือไม่ ถ้าเป็นเช่นนั้นเพิ่มลงELSE 0ในCASEงบของคุณ SUMของค่าNULLNULL

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, 



6

ใช้COALESCEซึ่งจะส่งคืนค่าที่ไม่ใช่ค่า null แรกเช่น

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

จะตั้งประสบความสำเร็จเป็น 0 NULLถ้ามันจะกลับมาเป็น


1

เพิ่มคำสั่งอื่นให้กับเคสของคุณเพื่อให้ค่าดีฟอลต์เป็นศูนย์หากไม่พบเงื่อนไขการทดสอบ ในตอนนี้หากไม่พบเงื่อนไขการทดสอบ NULL กำลังถูกส่งไปยังฟังก์ชัน 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

หากคุณใช้ Presto, AWS Athena และอื่น ๆ จะไม่มีฟังก์ชั่น ISNULL () ให้ใช้:

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, 

ปัญหาที่นี่คือไม่มีคำสั่ง else คุณจะได้รับ Null เมื่อสถานะการทำงานไม่ใช่สถานะที่ระบุในคำอธิบายคอลัมน์ การเพิ่มอะไรก็ตามลงใน Null จะส่งผลให้ Null และนั่นคือปัญหาของแบบสอบถามนี้

โชคดี!


0

โดยทำตามคำตอบก่อนหน้านี้ฉันได้สูญเสียชื่อคอลัมน์ของฉันในฐานข้อมูลเซิร์ฟเวอร์ SQL แต่ต่อไปนี้ไวยากรณ์นี้ช่วยให้ฉันรักษา ColumnName เช่นกัน

ISNULL(MyColumnName, 0) MyColumnName
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.