问题 如何确定Postgres中的数组中是否包含NULL?


如何确定Postgres中的数组中是否包含NULL?目前使用Postgres 9.3.3。

如果我用以下选项进行测试,则返回 contains_null = false

select ARRAY[NULL,1,2,3,4,NULL]::int[] @> ARRAY[NULL]::int[] AS contains_null
select ARRAY[NULL,1,2,3,4,NULL]::int[] @> NULL AS contains_null

我也尝试过:

  1. @>(包含)
  2. <@(包含在内)
  3. && (交叠)

4081
2018-03-27 17:32


起源

在类似问题下的更多解决方案: stackoverflow.com/questions/34848009/... - Erwin Brandstetter


答案:


select exists (
    select 1 
    from unnest(array[1, null]) s(a)
    where a is null
);
 exists 
--------
 t

或更短:

select bool_or(a is null)
from unnest(array[1, null]) s(a)
;
 bool_or 
---------
 t

3
2018-03-27 18:02



有没有比使用unfst更好的方法?我已经考虑过了,但是有超过100万条记录,其中一列可能有30多个数组项,不需要产生相当多的记录。这是一张审计表。 - thames
@thames我觉得不合适的会表现得很好,我不知道其他任何方式。 - Clodoaldo Neto


我不想用 unnest 或者,所以我使用了比较 array_length 运用 array_remove 解决类似的问题。测试9.4.1,但应该在9.3.3中工作。

SELECT
ARRAY_LENGTH(ARRAY[1,null], 1) > ARRAY_LENGTH(ARRAY_REMOVE(ARRAY[1,null], NULL), 1) 
OR ARRAY_LENGTH(ARRAY_REMOVE(ARRAY[1,null], NULL), 1) IS NULL
---------
t

4
2018-02-11 17:08





还有一个建筑,比如@Clodoaldo Neto提出的建议。更紧凑的表达:

CREATE TEMPORARY TABLE null_arrays (
      id serial primary key
    , array_data int[]
);

INSERT INTO null_arrays (array_data)
VALUES
      (ARRAY[1,2, NULL, 4, 5])
    , (ARRAY[1,2, 3, 4, 5])
    , (ARRAY[NULL,2, 3, NULL, 5])
;

SELECT 
    *
FROM 
    null_arrays
WHERE
    TRUE = ANY (SELECT unnest(array_data) IS NULL)
;

4
2018-03-14 19:52





理想情况下你会写:

SELECT
    NULL IS NOT DISTINCT FROM ANY ARRAY[NULL,1,2,3,4,NULL]::int[];

但解析器无法识别 IS NOT DISTINCT FROM 作为这里的运算符的有效语法,我找不到它的运算符别名。

你必须:

CREATE FUNCTION opr_isnotdistinctfrom(anyelement, anyelement)
RETURNS boolean LANGUAGE SQL IMMUTABLE AS $$
SELECT $1 IS NOT DISTINCT FROM $2; 
$$;

CREATE OPERATOR <<>> (
    PROCEDURE = opr_isnotdistinctfrom,
    LEFTARG = anyelement,
    RIGHTARG = anyelement
);

SELECT NULL <<>> ANY (ARRAY[NULL,1,2,3,4,NULL]::int[]);

这似乎有点可怕,但应该优化出来就好了。


2
2018-03-28 00:44





似乎以下在PostgreSQL 10.1中运行良好。

CREATE TABLE my_table
(
    ...
    my_set  int[] NOT NULL,
    ...
);

SELECT
    my_set
FROM
    my_table
WHERE
    array_position(my_set, NULL) IS NOT NULL;

2
2017-12-26 22:28