Cara terbaik untuk memeriksa “nilai kosong atau nol”

176

Apa cara terbaik untuk memeriksa apakah nilainya null atau string kosong dalam pernyataan Postgres sql?

Nilai dapat berupa ekspresi yang panjang sehingga lebih disukai ditulis hanya sekali dalam pemeriksaan.

Saat ini saya menggunakan:

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

Tapi itu terlihat agak jelek.

stringexpressionbisa berupa char(n)kolom atau ekspresi yang mengandungchar(n) kolom dengan spasi tambahan.

Apa cara terbaik?

Andrus
sumber
3
Menggunakan charhampir selalu merupakan pilihan yang salah karena padding (dan menghasilkan ruang buang). Namun terlepas dari itu: Saya tidak berpikir ada solusi yang lebih baik.
a_horse_with_no_name
Kenapa jelek? Logis dan terbaca.
klin
1
@ a_horse_with_no_name: Saya rasa ada.
Erwin Brandstetter

Jawaban:

284

Ekspresi stringexpression = ''menghasilkan:

TRUE   .. untuk ''(atau untuk string apa pun yang hanya terdiri dari spasi dengan tipe data char(n))
NULL   .. untukNULL
FALSE .. untuk hal lain

Jadi untuk memeriksa: " stringexpressionapakah NULL atau kosong" :

(stringexpression = '') IS NOT FALSE

Atau pendekatan sebaliknya (mungkin lebih mudah dibaca):

(stringexpression <> '') IS NOT TRUE

Bekerja untuk semua jenis karakter termasuk char(n). Manual tentang operator perbandingan.

Atau gunakan ekspresi asli Anda tanpa trim(), yang merupakan noise mahal untuk char(n)(lihat di bawah), atau salah untuk tipe karakter lain: string yang hanya terdiri dari spasi akan dilewatkan sebagai string kosong.

coalesce(stringexpression, '') = ''

Tetapi ekspresi di atas lebih cepat.

Menyatakan yang sebaliknya bahkan lebih sederhana: " stringexpressionbukan NULL atau kosong" :

stringexpression <> ''

Tentang char(n)

Ini adalah tentang tipe data char(n), singkatan: character(n). ( char/ characterkependekan dari char(1)/ character(1).) Penggunaannya tidak disarankan di Postgres :

Dalam sebagian besar situasi textatau character varyingharus digunakan sebagai gantinya.

Jangan bingung char(n)dengan tipe karakter lain yang bergunavarchar(n) , varchar, textatau"char" (dengan tanda kutip ganda).

Dalam char(n)sebuah string kosong tidak berbeda dari string lain yang terdiri dari ruang saja. Semua ini dilipat menjadi n spasi dichar(n) per definisi jenis. Secara logis berikut bahwa ekspresi di atas berfungsi char(n)juga - sama seperti ini (yang tidak akan bekerja untuk tipe karakter lain):

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

Demo

String kosong sama dengan string spasi apa pun saat dilemparkan ke char(n) :

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

Hasil:

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

Uji "string kosong atau kosong" dengan 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);

Hasil:

stringexpression | base_test | test1 | test2 | coalesce1 | coalesce2 | menyatu3
------------------ + ----------- + ------- + ------- + --- -------- + ----------- + -----------
 foo | f | f | f | f | f | f
                  | t | t | t | t | t | t
                  | t | t | t | t | t | t
 null              | null       | t | t | t | t | t

Uji "string kosong atau kosong" dengan 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);

Hasil:

stringexpression | base_test | test1 | test2 | coalesce1 | coalesce2 | menyatu3
------------------ + ----------- + ------- + ------- + --- -------- + ----------- + -----------
 foo | f | f | f | f | f | f
                  | t | t | t | t | f | f
                  | f | f | f | f | f | f
 null              | null       | t | t | t | t | f

db <> biola di sini
Old sqlfiddle

Terkait:

Erwin Brandstetter
sumber
2
@a_horse_with_no_name: OP meminta best way to check if value is null or empty string. The trim()panggilan (relatif) mahal - dan hanya tidak perlu. Saya menambahkan lebih banyak tentang char(n)dan "string kosong".
Erwin Brandstetter
1
Anda menulis bahwa ekspresi string apa pun yang hanya berisi spasi sama dengan ''. Dapatkah saya menghapus trim dan gunakan coalesce(stringexpression,'')=''untuk memeriksa. Ini terlihat lebih mudah dibaca dibandingkan jawaban Anda.
Andrus
1
@ Andrus: Ya, Anda bisa. Saya menambahkan itu dan beberapa lagi ke jawabannya.
Erwin Brandstetter
3
select coalesce(' ', '') = '' mengembalikan salah. Jadi TRIM () diperlukan
Andrus
1
Tetapi coalesce(' '::char(5), '') = ''tidak. Saya akan menggunakan salah satu dari dua ekspresi teratas dalam hal apa pun, yang berfungsi untuk semua jenis karakter dan tercepat dan terbersih.
Erwin Brandstetter
46

Untuk memeriksa nol dan kosong:

coalesce(string, '') = ''

Untuk memeriksa null, kosong, dan spasi (pangkas string)

coalesce(TRIM(string), '') = ''
sam
sumber
3
Saya suka kesederhanaan / kejelasan jawaban ini.
stwr667
12

Memeriksa panjang string juga berfungsi dan kompak:

where length(stringexpression) > 0;
yglodt
sumber
Apakah Anda memeriksa ini untuk kasing NULL?
Flinsch
1
Ya saya lakukan. Itu tidak mengembalikan bidang string kosong atau nol.
yglodt
Jika Anda hanya perlu memeriksa hanya nilai kosong, coba ini -> where length(stringexpression) = 0;. Ini bekerja untuk saya.
Kushan Gunasekera
2

Jika mungkin ada ruang trailing kosong, mungkin tidak ada solusi yang lebih baik. COALESCEhanya untuk masalah seperti milikmu.

Świstak35
sumber
1

Sesuatu yang saya lihat digunakan orang stringexpression > ''. Ini mungkin bukan yang tercepat, tetapi kebetulan salah satu yang terpendek.

Mencobanya di MS SQL dan juga PostgreSQL.

TarasB
sumber
1

cara lain adalah

nullif(trim(stringExpression),'') is not null
Mowazzem Hosen
sumber
1
IMHO jawaban terbaik
Jeff
0

Cara yang saya pilih untuk membandingkan bidang yang dapat dibatalkan adalah: NULLIF (nullablefield,: ParameterValue) IS NULL DAN NULLIF (: ParameterValue, nullablefield) IS NULL. Ini rumit tetapi digunakan secara universal sementara Coalesce tidak mungkin dalam beberapa kasus.

Penggunaan NULLIF kedua dan kebalikan adalah karena "NULLIF (nullablefield,: ParameterValue) IS NULL" akan selalu mengembalikan "true" jika parameter pertama adalah null.

Danilo da Silva
sumber
0

Jika database memiliki sejumlah besar catatan maka null checkdapat mengambil lebih banyak waktu Anda dapat menggunakan cek kosong dengan cara yang berbeda seperti: 1) where columnname is null 2) where not exists() 3)WHERE (case when columnname is null then true end)

Ambrish Rajput
sumber
0

Banyak jawaban adalah cara terpendek, bukan cara terbaik jika kolom memiliki banyak nol. Menghentikan pemeriksaan memungkinkan pengoptimal untuk mengevaluasi pemeriksaan lebih cepat karena tidak harus melakukan pekerjaan pada kondisi lainnya.

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

Perbandingan string tidak perlu dievaluasi karena kondisi pertama salah.

John VE
sumber