9.5 या बाद के संस्करण पोस्ट करें
या array_position()
. का प्रयोग करें . मूल रूप से:
SELECT array_position(arr, NULL) IS NOT NULL AS array_has_null
नीचे डेमो देखें।
9.3 या बाद के संस्करण पोस्ट करें
आप अंतर्निहित कार्यों के साथ परीक्षण कर सकते हैं array_remove()
या array_replace()
।
9.1 या किसी भी संस्करण को पोस्ट करता है
अगर आप जानते हैं एक एकल तत्व जो आपके सरणियों में कभी मौजूद नहीं हो सकता, आप इसका उपयोग कर सकते हैं तेज़ अभिव्यक्ति। मान लीजिए, आपके पास सकारात्मक संख्याओं की एक सरणी है, और -1
इसमें कभी नहीं हो सकता:
-1 = ANY(arr) IS NULL
विस्तृत विवरण के साथ संबंधित उत्तर:
- पोस्टग्रेएसक्यूएल में सभी एनयूएलएल सरणी है
अगर आप बिल्कुल निश्चित नहीं हो सकते , आप कर सकते थे महँगे लेकिन सुरक्षित में से किसी एक पर वापस आना unnest()
. के साथ तरीके . पसंद:
(SELECT bool_or(x IS NULL) FROM unnest(arr) x)
या:
EXISTS (SELECT 1 FROM unnest(arr) x WHERE x IS NULL)
लेकिन आपके पास तेज़ और सुरक्षित हो सकता है CASE
. के साथ अभिव्यक्ति। एक असंभावित संख्या का उपयोग करें और यदि यह मौजूद होना चाहिए तो सुरक्षित विधि पर वापस आएं। आप मामले का इलाज करना चाह सकते हैं arr IS NULL
अलग से। नीचे डेमो देखें।
डेमो
SELECT num, arr, expect
, -1 = ANY(arr) IS NULL AS t_1 -- 50 ms
, (SELECT bool_or(x IS NULL) FROM unnest(arr) x) AS t_2 -- 754 ms
, EXISTS (SELECT 1 FROM unnest(arr) x WHERE x IS NULL) AS t_3 -- 521 ms
, CASE -1 = ANY(arr)
WHEN FALSE THEN FALSE
WHEN TRUE THEN EXISTS (SELECT 1 FROM unnest(arr) x WHERE x IS NULL)
ELSE NULLIF(arr IS NOT NULL, FALSE) -- catch arr IS NULL -- 55 ms
-- ELSE TRUE -- simpler for columns defined NOT NULL -- 51 ms
END AS t_91
, array_replace(arr, NULL, 0) <> arr AS t_93a -- 99 ms
, array_remove(arr, NULL) <> arr AS t_93b -- 96 ms
, cardinality(array_remove(arr, NULL)) <> cardinality(arr) AS t_94 -- 81 ms
, COALESCE(array_position(arr, NULL::int), 0) > 0 AS t_95a -- 49 ms
, array_position(arr, NULL) IS NOT NULL AS t_95b -- 45 ms
, CASE WHEN arr IS NOT NULL
THEN array_position(arr, NULL) IS NOT NULL END AS t_95c -- 48 ms
FROM (
VALUES (1, '{1,2,NULL}'::int[], true) -- extended test case
, (2, '{-1,NULL,2}' , true)
, (3, '{NULL}' , true)
, (4, '{1,2,3}' , false)
, (5, '{-1,2,3}' , false)
, (6, NULL , null)
) t(num, arr, expect);
परिणाम:
num | arr | expect | t_1 | t_2 | t_3 | t_91 | t_93a | t_93b | t_94 | t_95a | t_95b | t_95c -----+-------------+--------+--------+------+-----+------+-------+-------+------+-------+-------+------- 1 | {1,2,NULL} | t | t | t | t | t | t | t | t | t | t | t 2 | {-1,NULL,2} | t | f --!! | t | t | t | t | t | t | t | t | t 3 | {NULL} | t | t | t | t | t | t | t | t | t | t | t 4 | {1,2,3} | f | f | f | f | f | f | f | f | f | f | f 5 | {-1,2,3} | f | f | f | f | f | f | f | f | f | f | f 6 | NULL | NULL | t --!! | NULL | f | NULL | NULL | NULL | NULL | f | f | NULL
ध्यान दें कि array_remove()
और array_position()
बहु-आयामी सरणियों के लिए अनुमति नहीं है . t_93a
. के दाईं ओर सभी भाव केवल 1-आयामी सरणियों के लिए काम करते हैं।
db<>फिडल यहाँ - अधिक परीक्षणों के साथ 13 पोस्टग्रेज करें
पुराना sqlfiddle
बेंचमार्क सेटअप
जोड़े गए समय पोस्टग्रेज़ 9.5 में 200k पंक्तियों के साथ बेंचमार्क परीक्षण . से हैं . यह मेरा सेटअप है:
CREATE TABLE t AS
SELECT row_number() OVER() AS num
, array_agg(elem) AS arr
, bool_or(elem IS NULL) AS expected
FROM (
SELECT CASE WHEN random() > .95 THEN NULL ELSE g END AS elem -- 5% NULL VALUES
, count(*) FILTER (WHERE random() > .8)
OVER (ORDER BY g) AS grp -- avg 5 element per array
FROM generate_series (1, 1000000) g -- increase for big test case
) sub
GROUP BY grp;
फ़ंक्शन रैपर
बार-बार उपयोग के लिए , मैं Postgres 9.5 . में एक फ़ंक्शन बनाउंगा इस तरह:
CREATE OR REPLACE FUNCTION f_array_has_null (anyarray)
RETURNS bool
LANGUAGE sql IMMUTABLE PARALLEL SAFE AS
'SELECT array_position($1, NULL) IS NOT NULL';
PARALLEL SAFE
केवल पोस्टग्रेज़ 9.6 या बाद के संस्करण के लिए।
बहुरूपी इनपुट प्रकार का उपयोग करके यह किसी भी . के लिए कार्य करता है सरणी प्रकार, न केवल int[]
।
इसे IMMUTABLE
बनाएं प्रदर्शन अनुकूलन और अनुक्रमणिका अभिव्यक्तियों की अनुमति देने के लिए।
- क्या PostgreSQL "एक्सेंट असंवेदनशील" कॉलेशन का समर्थन करता है?
लेकिन इसे STRICT
न बनाएं , जो "फ़ंक्शन इनलाइनिंग" को अक्षम कर देगा और प्रदर्शन को ख़राब कर देगा क्योंकि array_position()
STRICT
नहीं है अपने आप। देखें:
- STRICT संशोधक के बिना कार्य तेजी से निष्पादित होता है?
अगर आपको केस को पकड़ने की जरूरत है arr IS NULL
:
CREATE OR REPLACE FUNCTION f_array_has_null (anyarray)
RETURNS bool
LANGUAGE sql IMMUTABLE PARALLEL SAFE AS
'SELECT CASE WHEN $1 IS NOT NULL
THEN array_position($1, NULL) IS NOT NULL END';
पोस्टग्रेज के लिए 9.1 t_91
का उपयोग करें ऊपर से अभिव्यक्ति। शेष अपरिवर्तित लागू होता है।
निकट से संबंधित:
- यह कैसे निर्धारित करें कि पोस्टग्रेज में NULL एक सरणी में समाहित है या नहीं?