PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

जांचें कि पोस्टग्रेज सरणी में NULL मौजूद है या नहीं

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 एक सरणी में समाहित है या नहीं?


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. किसी फ़ील्ड में PostgreSQL अनुक्रम बनाना (जो रिकॉर्ड की आईडी नहीं है)

  2. रेल पर रूबी:क्या डेटाबेस से आइटम खींचने और उन्हें एक निर्दिष्ट क्रम में वापस करने का कोई तरीका है?

  3. पोस्टग्रेज में रेगुलर एक्सप्रेशन ढूंढें और बदलें

  4. SQLAlchemy घोषणात्मक:ट्रिगर्स और इंडेक्स को परिभाषित करना (पोस्टग्रेज 9)

  5. Postgres में ब्लॉब डेटाटाइप का उपयोग कैसे करें