ผู้ประกอบการ
นี้จะสร้าง@ ประกอบการที่ชาญฉลาดของแดเนียล 
ในขณะที่ถูกที่มันสร้างฟังก์ชั่นคำสั่งผสม / ผู้ประกอบการใช้ประเภท polymorphic จากนั้นใช้ได้กับทุกประเภท - เช่นเดียวกับโครงสร้าง และทำให้ฟังก์ชั่น
IMMUTABLE
CREATE FUNCTION is_distinct_from(anyelement, anyelement)
  RETURNS bool LANGUAGE sql IMMUTABLE AS 
'SELECT $1 IS DISTINCT FROM $2';
CREATE OPERATOR <!> (
  PROCEDURE = is_distinct_from(anyelement,anyelement),
  LEFTARG  = anyelement
, RIGHTARG = anyelement
);
การค้นหาอย่างรวดเร็วด้วย symbolhoundว่างเปล่าดังนั้นผู้ปฏิบัติงาน<!>จึงไม่ได้ใช้งานในโมดูลใด ๆ
ถ้าคุณจะใช้ดำเนินการนี้เป็นจำนวนมากคุณอาจเนื้อมันออกมาบางมากขึ้นเพื่อช่วยในการวางแผนการสอบถาม ( เช่น losthorse ปัญหาในความคิดเห็น ) สำหรับผู้เริ่มต้นคุณสามารถเพิ่มCOMMUTATORและส่วนNEGATORคำสั่งเพื่อช่วยเพิ่มประสิทธิภาพการสืบค้น แทนที่CREATE OPERATORจากด้านบนด้วยสิ่งนี้:
CREATE OPERATOR <!> (
  PROCEDURE = is_distinct_from(anyelement,anyelement),
  LEFTARG  = anyelement
, RIGHTARG = anyelement
, COMMUTATOR = <!>
, NEGATOR = =!=
);
และเพิ่ม:
CREATE FUNCTION is_not_distinct_from(anyelement, anyelement)
  RETURNS bool LANGUAGE sql IMMUTABLE AS 
'SELECT $1 IS NOT DISTINCT FROM $2';
CREATE OPERATOR =!= (
  PROCEDURE = is_not_distinct_from(anyelement,anyelement),
  LEFTARG  = anyelement
, RIGHTARG = anyelement
, COMMUTATOR = =!=
, NEGATOR = <!>
);
แต่ส่วนเพิ่มเติมจะไม่ช่วยกรณีการใช้งานในมือและดัชนีธรรมดายังคงไม่ถูกใช้ มันซับซ้อนกว่านี้มากในการบรรลุเป้าหมาย (ฉันยังไม่ได้ลอง) อ่านบท"ข้อมูลการเพิ่มประสิทธิภาพของผู้ปฏิบัติงาน"ในคู่มือสำหรับรายละเอียด
กรณีทดสอบ
กรณีทดสอบในคำถามสามารถเกิดขึ้นได้ก็ต่อเมื่อค่าทั้งหมดในอาร์เรย์เหมือนกัน สำหรับอาร์เรย์ในคำถาม ( '{null,A}'::text[]) ผลลัพธ์จะเป็นจริงเสมอ นั่นตั้งใจหรือไม่ ฉันได้เพิ่มการทดสอบอื่นสำหรับ "IS DISTINCT FROM ALL":
SELECT foo
     , foo <!> ANY ('{null,A}'::text[]) AS chk_any
     , foo <!> ALL ('{null,A}'::text[]) AS chk_all
FROM (
   VALUES ('A'),('Z'),(NULL)
   ) z(foo)
 foo | chk_any | chk_all
-----+---------+---------
 A   | t       | f
 Z   | t       | t
     | t       | f
ทางเลือกกับผู้ประกอบการมาตรฐาน
foo IS DISTINCT FROM ANY (test_arr) -- illegal syntax
สามารถเกือบถูกแปลมา
foo = ALL (test_arr) IS NOT TRUE
foo = ALL (test_arr) ให้ผลผลิต ...
TRUE  .. หากองค์ประกอบทั้งหมดเป็นfoo
FALSE.. หากNOT NULLองค์ประกอบใด ๆคือ<> foo
NULL  .. หากอย่างน้อยหนึ่งองค์ประกอบIS NULLและองค์ประกอบไม่เป็น<> foo
กรณีมุมที่เหลืออยู่คือ
- foo IS NULL
-   และ test_arrประกอบด้วยอะไรนอกจากNULLองค์ประกอบ
หากสามารถถูกตัดออกเราก็จะเสร็จ ดังนั้นการใช้การทดสอบง่ายถ้า
- NOT NULLคอลัมน์ถูกกำหนด 
- หรือคุณรู้ว่าอาร์เรย์ไม่เคยเป็น NULL ทั้งหมด
อื่นทดสอบเพิ่มเติม:
AND ('A' = ALL(test_arr) IS NOT NULL OR 
     'B' = ALL(test_arr) IS NOT NULL OR
     foo IS NOT NULL)
ที่ไหน'A'และ'B'สามารถใด ๆค่าที่แตกต่างกัน คำอธิบายและทางเลือกภายใต้คำถามที่เกี่ยวข้องนี้ใน SO: 
เป็นอาร์เรย์ NULL ทั้งหมดใน PostgreSQL
อีกครั้งถ้าคุณรู้เกี่ยวกับค่าใด ๆ ที่ไม่สามารถมีอยู่ได้test_arrตัวอย่างเช่นสตริงว่าง''คุณยังสามารถทำให้:
AND ('' = ALL(test_arr) IS NOT NULL OR
     foo IS NOT NULL)
นี่คือเมทริกซ์ทดสอบที่สมบูรณ์เพื่อตรวจสอบชุดค่าผสมทั้งหมด:
SELECT foo, test_arr
     , foo = ALL(test_arr) IS NOT TRUE  AS test_simple
     , foo = ALL(test_arr) IS NOT TRUE
       AND ('A' = ALL(test_arr) IS NOT NULL OR
            'B' = ALL(test_arr) IS NOT NULL OR 
            foo IS NOT NULL)            AS test_sure 
FROM (
   VALUES ('A'),('Z'),(NULL)
   ) v(foo)
CROSS JOIN (
   VALUES ('{null,A}'::text[]),('{A,A}'),('{null,null}')
   ) t(test_arr)
 foo |  test_arr   | test_simple | test_sure
-----+-------------+-------------+-----------
 A   | {NULL,A}    | t           | t
 A   | {A,A}       | f           | f   -- only TRUE case
 A   | {NULL,NULL} | t           | t
 Z   | {NULL,A}    | t           | t
 Z   | {A,A}       | t           | t
 Z   | {NULL,NULL} | t           | t
     | {NULL,A}    | t           | t
     | {A,A}       | t           | t
     | {NULL,NULL} | t           | f   -- special case
นี่เป็น verbose มากกว่าโซลูชันของ AndriyEXCEPTแต่มันเร็วกว่ามาก