Cách tốt nhất để kiểm tra giá trị trống rỗng hoặc giá trị null


176

Cách tốt nhất để kiểm tra xem giá trị là null hay chuỗi rỗng trong các câu lệnh sql Postgres là gì?

Giá trị có thể là biểu thức dài vì vậy tốt hơn là nó chỉ được viết một lần trong kiểm tra.

Hiện tại tôi đang sử dụng:

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

Nhưng có vẻ hơi xấu xí.

stringexpressioncó thể là char(n)cột hoặc biểu thức chứa char(n)các cột có dấu cách.

Cách tốt nhất là gì?


3
Sử dụng charhầu như luôn luôn là lựa chọn sai do đệm (và kết quả là lãng phí không gian). Nhưng ngoài ra: tôi không nghĩ có một giải pháp tốt hơn.
a_horse_with_no_name

Tại sao xấu xí? Hợp lý và dễ đọc.
klin

1
@a_horse_with_no_name: Tôi nghĩ là có.
Erwin Brandstetter

Câu trả lời:


282

Biểu thức stringexpression = ''mang lại:

TRUE   .. cho ''(hoặc cho bất kỳ chuỗi nào chỉ bao gồm khoảng trắng với kiểu dữ liệu char(n))
NULL   .. cho NULL
FALSE .. cho mọi thứ khác

Vì vậy, để kiểm tra: " stringexpressionlà NULL hoặc trống" :

(stringexpression = '') IS NOT FALSE

Hoặc cách tiếp cận ngược lại (có thể dễ đọc hơn):

(stringexpression <> '') IS NOT TRUE

Hoạt động cho bất kỳ loại nhân vật bao gồm char(n). Hướng dẫn về toán tử so sánh.

Hoặc sử dụng biểu thức ban đầu của bạn mà không có trim()nhiễu gây tốn kém cho char(n)(xem bên dưới) hoặc không chính xác cho các loại ký tự khác: các chuỗi chỉ bao gồm các khoảng trắng sẽ chuyển qua dưới dạng chuỗi trống.

coalesce(stringexpression, '') = ''

Nhưng các biểu thức ở đầu nhanh hơn.

Khẳng định điều ngược lại thậm chí còn đơn giản hơn: " stringexpressionkhông phải là NULL cũng không trống rỗng" :

stringexpression <> ''

Trong khoảng char(n)

Đây là về kiểu dữ liệu char(n), viết tắt của : character(n). ( char/ characterviết tắt của char(1)/ character(1).) Việc sử dụng nó không được khuyến khích trong Postgres :

Trong hầu hết các tình huống texthoặc character varyingnên được sử dụng thay thế.

Đừng nhầm lẫn char(n)với các loại khác, hữu ích, nhân vật varchar(n), varchar, texthoặc"char" (trong dấu ngoặc kép).

Trong char(n)một chuỗi rỗng không khác với bất kỳ chuỗi nào khác chỉ bao gồm các khoảng trắng. Tất cả những thứ này được gấp lại thành n khoảng trắng char(n)theo định nghĩa của loại. Nó tuân theo logic rằng các biểu thức trên cũng hoạt động char(n)tốt - cũng giống như các biểu thức này (sẽ không hoạt động đối với các loại ký tự khác):

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

Bản giới thiệu

Chuỗi rỗng bằng với bất kỳ chuỗi khoảng trắng nào khi truyền tới char(n):

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

Kết quả:

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

Kiểm tra "null hoặc chuỗi rỗng" với 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);

Kết quả:

biểu hiện chuỗi | cơ sở | kiểm tra1 | kiểm tra2 | hợp nhất1 | hợp nhất2 | hợp nhất3
------------------ + ----------- + ------- + ------- + --- -------- + ----------- + -----------
 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

Kiểm tra "null hoặc chuỗi rỗng" với 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);

Kết quả:

biểu hiện chuỗi | cơ sở | kiểm tra1 | kiểm tra2 | hợp nhất1 | hợp nhất2 | hợp nhất3
------------------ + ----------- + ------- + ------- + --- -------- + ----------- + -----------
 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 <> fiddle ở đây sqlfiddle

Liên quan:


2
@a_horse_with_no_name: OP yêu cầu best way to check if value is null or empty string. Cuộc trim()gọi này (tương đối) đắt tiền - và chỉ không cần thiết. Tôi đã thêm nhiều hơn về char(n)và "chuỗi trống".
Erwin Brandstetter

1
Bạn đã viết rằng bất kỳ biểu thức chuỗi nào chỉ chứa khoảng trắng đều bằng ''. Tôi có thể loại bỏ trim và sử dụng coalesce(stringexpression,'')=''để kiểm tra. Điều này có vẻ dễ đọc hơn đối với tôi so với câu trả lời của bạn.
Andrus

1
@Andrus: Vâng, bạn có thể. Tôi đã thêm điều đó và một số chi tiết cho câu trả lời.
Erwin Brandstetter

3
select coalesce(' ', '') = '' trả về sai. Vì vậy, TRIM () là bắt buộc
Andrus

1
Nhưng coalesce(' '::char(5), '') = ''không. Tôi sẽ sử dụng một trong hai biểu thức hàng đầu trong mọi trường hợp, hoạt động cho bất kỳ loại ký tự nào và nhanh nhất và sạch nhất.
Erwin Brandstetter

46

Để kiểm tra null và trống:

coalesce(string, '') = ''

Để kiểm tra null, trống và khoảng trắng (cắt chuỗi)

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

3
Tôi thích sự đơn giản / rõ ràng của câu trả lời này.
stwr667

11

Kiểm tra độ dài của chuỗi cũng hoạt động và nhỏ gọn:

where length(stringexpression) > 0;

Bạn đã kiểm tra điều này cho trường hợp NULL?
Flinsch

1
Vâng, tôi đã làm. Nó không trả về các trường chuỗi rỗng cũng như null.
yglodt

Nếu bạn chỉ cần kiểm tra các giá trị trống, thì hãy thử điều này -> where length(stringexpression) = 0;. Điều này làm việc cho tôi.
Kushan Gunasekera

2

Nếu có thể có khoảng trống ở cuối, có lẽ không có giải pháp nào tốt hơn. COALESCEchỉ dành cho các vấn đề như của bạn.


1

Một cái gì đó mà tôi thấy mọi người sử dụng là stringexpression > ''. Đây có thể không phải là nhanh nhất, nhưng tình cờ là một trong những ngắn nhất.

Đã thử nó trên MS SQL cũng như trên PostgreSQL.



0

Cách được ưu tiên của tôi để so sánh các trường nullable là: NULLIF (nullablefield ,: ParameterValue) IS NULL AND NULLIF (: ParameterValue, nullablefield) IS NULL. Điều này là cồng kềnh nhưng được sử dụng phổ biến trong khi Coalesce là không thể trong một số trường hợp.

Việc sử dụng thứ hai và nghịch đảo của NULLIF là vì "NULLIF (nullablefield ,: ParameterValue) IS NULL" sẽ luôn trả về "true" nếu tham số đầu tiên là null.


0

Nếu cơ sở dữ liệu có số lượng bản ghi lớn thì null checkcó thể mất nhiều thời gian hơn, bạn có thể sử dụng kiểm tra null theo các cách khác nhau như: 1) where columnname is null 2) where not exists() 3)WHERE (case when columnname is null then true end)


0

Rất nhiều câu trả lời là cách ngắn nhất, không nhất thiết là cách tốt nhất nếu cột có nhiều null. Việc phá vỡ các kiểm tra cho phép trình tối ưu hóa đánh giá kiểm tra nhanh hơn vì nó không phải thực hiện công việc ở điều kiện khác.

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

So sánh chuỗi không cần phải được đánh giá vì điều kiện đầu tiên là sai.

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.