วิธีที่ดีที่สุดในการตรวจสอบ“ ค่าว่างหรือค่าว่าง”


176

วิธีที่ดีที่สุดในการตรวจสอบว่าค่าเป็นโมฆะหรือสตริงว่างในงบ Postgres sql คืออะไร?

ค่าสามารถเป็นนิพจน์แบบยาวดังนั้นจึงควรเขียนว่าตรวจสอบเพียงครั้งเดียว

ขณะนี้ฉันกำลังใช้:

coalesce( trim(stringexpression),'')=''

แต่มันดูน่าเกลียดนิดหน่อย

stringexpressionอาจเป็นchar(n)คอลัมน์หรือนิพจน์ที่มีchar(n)คอลัมน์ที่มีช่องว่างต่อท้าย

วิธีที่ดีที่สุดคืออะไร


3
การใช้งานcharมักเป็นทางเลือกที่ผิดเนื่องจากการขยาย (และทำให้พื้นที่ใช้งานหมด) แต่นอกเหนือจากนั้นฉันไม่คิดว่าจะมีทางออกที่ดีกว่า
a_horse_with_no_name

ทำไมน่าเกลียด ตรรกะและชัดเจน
klin

1
@a_horse_with_no_name: ฉันคิดว่ามี
Erwin Brandstetter

คำตอบ:


283

การแสดงออกstringexpression = ''ให้ผล:

TRUE   .. สำหรับ''(หรือสำหรับสตริงใด ๆ ที่ประกอบด้วยช่องว่างเฉพาะกับชนิดข้อมูลchar(n))
NULL   ..NULL
FALSE .. สำหรับสิ่งอื่นใด

ดังนั้นเพื่อตรวจสอบว่า: " stringexpressionเป็น NULL หรือเปล่า" :

(stringexpression = '') IS NOT FALSE

หรือวิธีย้อนกลับ (อาจอ่านง่ายกว่า):

(stringexpression <> '') IS NOT TRUE

การทำงานสำหรับพิมพ์ตัวอักษรใด ๆchar(n)รวมทั้ง คู่มือเกี่ยวกับตัวดำเนินการเปรียบเทียบ

หรือใช้นิพจน์ดั้งเดิมของคุณโดยไม่มีtrim()ซึ่งเป็นค่าใช้จ่ายสำหรับchar(n)(ดูด้านล่าง) หรือไม่ถูกต้องสำหรับประเภทอักขระอื่น ๆ : สตริงที่ประกอบด้วยช่องว่างเท่านั้นจะผ่านเป็นสตริงว่าง

coalesce(stringexpression, '') = ''

แต่การแสดงออกที่ด้านบนนั้นเร็วกว่า

การยืนยันสิ่งที่ตรงกันข้ามนั้นง่ายกว่า: " stringexpressionไม่มีค่าว่างหรือว่างเปล่า" :

stringexpression <> ''

เกี่ยวกับ char(n)

นี้เป็นเรื่องเกี่ยวกับชนิดข้อมูลสั้น:char(n) character(n)( char/ characterสั้นสำหรับchar(1)/ character(1).) การใช้งานไม่ได้ผลใน Postgres :

ในสถานการณ์ส่วนใหญ่textหรือcharacter varyingควรใช้แทน

อย่าสับสนchar(n)กับประเภทอื่น ๆ ที่มีประโยชน์, ตัวละครvarchar(n), varchar, textหรือ"char" (กับราคาสองครั้ง)

ในสตริงที่ว่างเปล่าchar(n)ไม่แตกต่างจากสายอื่น ๆ ใด ๆ ที่ประกอบด้วยช่องว่างเท่านั้น สิ่งเหล่านี้ทั้งหมดถูกพับเป็นช่องว่างnchar(n)ตามการกำหนดชนิด มันเป็นไปตามหลักเหตุผลว่านิพจน์ด้านบนใช้งานได้char(n)ดีเช่นกัน (ซึ่งไม่สามารถใช้ได้กับอักขระประเภทอื่น):

coalesce(stringexpression, '  ') = '  '
coalesce(stringexpression, '') = '       '

การสาธิต

สตริงว่างเท่ากับสตริงช่องว่างใด ๆ เมื่อส่งถึงchar(n):

SELECT ''::char(5) = ''::char(5)     AS eq1
     , ''::char(5) = '  '::char(5)   AS eq2
     , ''::char(5) = '    '::char(5) AS eq3;

ผลลัพธ์:

 eq1 | eq2 | eq3
 ----+-----+----
 t   | t   | t

ทดสอบสำหรับ "null หรือสตริงว่าง" ด้วย char(n):

SELECT stringexpression 
     , stringexpression = ''                   AS base_test
     , (stringexpression = '')  IS NOT FALSE   AS test1
     , (stringexpression <> '') IS NOT TRUE    AS test2
     , coalesce(stringexpression, '') = ''     AS coalesce1
     , coalesce(stringexpression, '  ') = '  ' AS coalesce2
     , coalesce(stringexpression, '') = '  '   AS coalesce3
FROM  (
   VALUES
     ('foo'::char(5))
   , ('')
   , ('   ')                -- not different from '' in char(n)
   , (NULL)
   ) sub(stringexpression);

ผลลัพธ์:

stringexpression | base_test | ทดสอบ 1 | ทดสอบ 2 | coalesce1 | coalesce2 | coalesce3
------------------ + ----------- + ------- + ------- + --- -------- + + ----------- -----------
 foo | f | f | f | f | f | ฉ
                  | t | t | t | t | t | เสื้อ
                  | t | t | t | t | t | เสื้อ
 null              | null       | t | t | t | t | เสื้อ

ทดสอบสำหรับ "null หรือสตริงว่าง" ด้วยtext:

SELECT stringexpression 
     , stringexpression = ''                   AS base_test
     , (stringexpression = '')  IS NOT FALSE   AS test1
     , (stringexpression <> '') IS NOT TRUE    AS test2
     , coalesce(stringexpression, '') = ''     AS coalesce1
     , coalesce(stringexpression, '  ') = '  ' AS coalesce2
     , coalesce(stringexpression, '') = '  '   AS coalesce3
FROM  (
   VALUES
     ('foo'::text)
   , ('')
   , ('   ')                -- different from '' in a sane character types
   , (NULL)
   ) sub(stringexpression);

ผลลัพธ์:

stringexpression | base_test | ทดสอบ 1 | ทดสอบ 2 | coalesce1 | coalesce2 | coalesce3
------------------ + ----------- + ------- + ------- + --- -------- + + ----------- -----------
 foo | f | f | f | f | f | ฉ
                  | t | t | t | t | f | ฉ
                  | f | f | f | f | f | ฉ
 null              | null       | t | t | t | t | ฉ

db <> fiddle here sqlfiddle ตัว
เก่า

ที่เกี่ยวข้อง:


2
@a_horse_with_no_name: OP best way to check if value is null or empty stringถามสำหรับ การtrim()โทรนั้นค่อนข้างแพงและไม่จำเป็น ฉันเพิ่มมากขึ้นเกี่ยวกับchar(n)และ "สตริงว่าง"
Erwin Brandstetter

1
คุณเขียนว่านิพจน์สตริงใด ๆ ''ที่มีพื้นที่เพียงอย่างเดียวคือเท่ากับ ฉันสามารถลบการตกแต่งและใช้coalesce(stringexpression,'')=''ในการตรวจสอบได้หรือไม่ นี่ดูเหมือนฉันจะอ่านได้มากกว่าคำตอบของคุณ
Andrus

1
@Andrus: ใช่คุณสามารถ ฉันเพิ่มที่และบางคำตอบ
Erwin Brandstetter

3
select coalesce(' ', '') = '' ผลตอบแทนที่เป็นเท็จ ดังนั้น TRIM () จึงจำเป็น
Andrus

1
แต่coalesce(' '::char(5), '') = ''ไม่ได้ ฉันจะใช้หนึ่งในสองนิพจน์ด้านบนไม่ว่าในกรณีใด ๆ ซึ่งใช้ได้กับตัวละครทุกประเภทและเร็วที่สุดและสะอาดที่สุด
Erwin Brandstetter

46

วิธีตรวจสอบค่าว่างและค่าว่าง:

coalesce(string, '') = ''

เพื่อตรวจสอบค่าว่างและช่องว่าง (ตัดสาย)

coalesce(TRIM(string), '') = ''

3
ฉันชอบความเรียบง่าย / ความชัดเจนของคำตอบนี้
stwr667

12

การตรวจสอบความยาวของสตริงใช้งานได้และกะทัดรัด:

where length(stringexpression) > 0;

คุณตรวจสอบเรื่องนี้สำหรับกรณี NULL หรือไม่?
Flinsch

1
ใช่ฉันทำ. มันจะไม่ส่งคืนค่าฟิลด์สตริงว่างหรือฟิลด์ว่าง
yglodt

หากคุณเพียงแค่ต้องตรวจสอบค่าที่ว่างเปล่าอย่างเดียวแล้วลองนี้ where length(stringexpression) = 0;-> มันใช้งานได้สำหรับฉัน
Kushan Gunasekera

2

หากอาจมีช่องว่างต่อท้ายอาจเป็นไปได้ว่าไม่มีวิธีแก้ปัญหาที่ดีกว่า COALESCEสำหรับปัญหาเช่นเดียวกับคุณ


1

stringexpression > ''สิ่งที่ผมเห็นคนที่ใช้คือ สิ่งนี้อาจไม่ใช่สิ่งที่เร็วที่สุด แต่เป็นสิ่งที่สั้นที่สุด

พยายามใช้ MS SQL และ PostgreSQL



0

วิธีที่เปรียบเทียบไว้ล่วงหน้าของฉันในการเปรียบเทียบเขตข้อมูล NULLIF คือ: NULLIF (nullablefield,: ParameterValue) IS NULL และ NULLIF (: ParameterValue, nullablefield) IS NULL นี่เป็นสิ่งที่ยุ่งยาก แต่ก็มีการใช้กันอย่างแพร่หลายในขณะที่ Coalesce นั้นเป็นไปไม่ได้ในบางกรณี

การใช้ NULLIF ที่สองและผกผันเป็นเพราะ "NULLIF (nullablefield,: ParameterValue) IS NULL" จะส่งคืน "true" เสมอหากพารามิเตอร์แรกเป็น Null


0

หากฐานข้อมูลมีจำนวนเรคคอร์ดจำนวนnull checkมากคุณสามารถใช้เวลามากขึ้นในการตรวจสอบค่า null ในรูปแบบต่าง ๆ เช่น: 1) where columnname is null 2) where not exists() 3)WHERE (case when columnname is null then true end)


0

คำตอบจำนวนมากเป็นวิธีที่สั้นที่สุดไม่ใช่วิธีที่ดีที่สุดหากคอลัมน์นั้นมีโมฆะจำนวนมาก การแยกการตรวจสอบช่วยให้เครื่องมือเพิ่มประสิทธิภาพประเมินการตรวจสอบได้เร็วขึ้นเนื่องจากไม่จำเป็นต้องทำงานกับเงื่อนไขอื่น

(stringexpression IS NOT NULL AND trim(stringexpression) != '')

การเปรียบเทียบสตริงไม่จำเป็นต้องประเมินเนื่องจากเงื่อนไขแรกเป็นเท็จ

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