Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何将ARRAY contains运算符与任意_Sql_Arrays_Postgresql_Postgresql 9.6 - Fatal编程技术网

Sql 如何将ARRAY contains运算符与任意

Sql 如何将ARRAY contains运算符与任意,sql,arrays,postgresql,postgresql-9.6,Sql,Arrays,Postgresql,Postgresql 9.6,我有一个表,其中一列是数组: CREATE TABLE inherited_tags ( id serial, tags text[] ); 样本值: INSERT INTO inherited_tags (tags) VALUES (ARRAY['A','B','C']), -- id: 1 (ARRAY['D','E']), -- id: 2 (ARRAY['A','B']), -- id: 3 (ARRAY['C','D

我有一个表,其中一列是数组:

CREATE TABLE inherited_tags (
   id serial,
   tags text[]
);
样本值:

INSERT INTO inherited_tags (tags) VALUES 
    (ARRAY['A','B','C']),  -- id: 1
    (ARRAY['D','E']),      -- id: 2
    (ARRAY['A','B']),      -- id: 3
    (ARRAY['C','D']),      -- id: 4
    (ARRAY['D','F']),      -- id: 5
    (ARRAY['A']);          -- id: 6
我想找到数组中包含单词子集的标记列中的行。例如,对于输入:

ARRAY[ARRAY['A','C'], ARRAY['F'], ARRAY['E']]::text[][]
我想查找包含('A'和'C')或('F')或('E')的所有行。例如,上面我应该得到ID为1、2、5的行

我希望我可以使用这样的语法:

SELECT * FROM inherited_tags WHERE
   tags @> ANY(ARRAY[ARRAY['A','C'], ARRAY['F'], ARRAY['E']]::text[][])
但我得到了一个错误:

ERROR:  operator does not exist: text[] @> text
LINE 1: SELECT * FROM inherited_tags where tags <@ ANY(ARRAY[ARRAY['...
错误:运算符不存在:text[]@>text

第1行:从继承的_标记中选择*,其中标记,我认为您不能使用单个条件,因为“包含C”要求

SELECT * 
FROM inherited_tags 
WHERE tags @> ARRAY['A','C']
   OR tags && array['F', 'E'];
tags@>ARRAY['A','C']
选择那些
tags
包含
ARRAY['A','C']
tags&&ARRAY['F','E']中所有元素的行。
选择至少包含
ARRAY['F','E']中一个标记的行。


更新的DB Fiddle:

我不认为你可以在一个条件下做到这一点,因为“包含C”要求

SELECT * 
FROM inherited_tags 
WHERE tags @> ARRAY['A','C']
   OR tags && array['F', 'E'];
tags@>ARRAY['A','C']
选择那些
tags
包含
ARRAY['A','C']
tags&&ARRAY['F','E']中所有元素的行。
选择至少包含
ARRAY['F','E']中一个标记的行。


更新的DB Fiddle:

问题源于
text[]
text[][]
数据类型在内部是相同的数据类型。数组有一个基类型和维度,
ANY
操作符总是提取要比较的基类型,它总是
text
而不是
text[]
。多维数组要求每个子元素的长度与其他子元素的长度相同,这一点没有帮助。您可以有
ARRAY[ARRAY['A','C',ARRAY['B','N']]
,但不能有
ARRAY[ARRAY[2,3],ARRAY[1]

简而言之,没有直接的方法可以使特定的查询工作。我也尝试为此创建一个函数和一个运算符,但由于不同的原因,这也不起作用。看看结果如何:

CREATE OR REPLACE FUNCTION check_tag_matches(
    IN leftside text[],
    IN rightside text)
  RETURNS BOOLEAN AS
$BODY$
 DECLARE rightarr text[];
BEGIN
  SELECT CAST(rightside as text[]) INTO rightarr;
  RETURN SELECT leftside @> rightarr;
END;
$BODY$
LANGUAGE plpgsql STABLE;

CREATE OPERATOR public.>>(
  PROCEDURE = check_tag_matches,
  LEFTARG = text[],
  RIGHTARG = text,
  COMMUTATOR = >>);
然后在测试时:

test=# SELECT * FROM inherited_tags WHERE
   tags >> ANY(ARRAY[ARRAY['A','M'], ARRAY['F','E'], ARRAY['E','R']]::text[][]);
ERROR:  malformed array literal: "A"
DETAIL:  Array value must start with "{" or dimension information.
CONTEXT:  SQL statement "SELECT CAST(rightside as text[])"
PL/pgSQL function check_tag_matches(text[],text) line 4 at SQL statement
似乎当你尝试在
ANY()
中使用多维数组时,比如
array[array['a','M'],array['F','E'],array['E','R']]::text[]
ANY()
中,它不会迭代
数组['a','M']
,然后是
array['F','E']
,然后是
array['E','R'>,而是迭代
。使用
unest
时也会发生同样的情况

test=# SELECT unnest(ARRAY[ARRAY['A','M'], ARRAY['F','E'], ARRAY['E','R']]::text[][]);
 unnest 
--------
 A
 M
 F
 E
 E
 R
(6 rows)

剩下的选项a是定义一个函数,该函数将读取
array\u length(rightside,1)
array\u length(rightside,2)
,并使用嵌套循环检查所有内容,或者可以发送多个查询以获取每个标记的继承标记,或者以某种方式重新构造数据。你甚至不能使用
rightside[1]
来访问
数组['A','M']
元素,你不得不进入最深层。

问题来自这样一个事实:
文本[]
文本[]
数据类型在内部是相同的数据类型。数组有一个基类型和维度,
ANY
操作符总是提取要比较的基类型,它总是
text
而不是
text[]
。多维数组要求每个子元素的长度与其他子元素的长度相同,这一点没有帮助。您可以有
ARRAY[ARRAY['A','C',ARRAY['B','N']]
,但不能有
ARRAY[ARRAY[2,3],ARRAY[1]

简而言之,没有直接的方法可以使特定的查询工作。我也尝试为此创建一个函数和一个运算符,但由于不同的原因,这也不起作用。看看结果如何:

CREATE OR REPLACE FUNCTION check_tag_matches(
    IN leftside text[],
    IN rightside text)
  RETURNS BOOLEAN AS
$BODY$
 DECLARE rightarr text[];
BEGIN
  SELECT CAST(rightside as text[]) INTO rightarr;
  RETURN SELECT leftside @> rightarr;
END;
$BODY$
LANGUAGE plpgsql STABLE;

CREATE OPERATOR public.>>(
  PROCEDURE = check_tag_matches,
  LEFTARG = text[],
  RIGHTARG = text,
  COMMUTATOR = >>);
然后在测试时:

test=# SELECT * FROM inherited_tags WHERE
   tags >> ANY(ARRAY[ARRAY['A','M'], ARRAY['F','E'], ARRAY['E','R']]::text[][]);
ERROR:  malformed array literal: "A"
DETAIL:  Array value must start with "{" or dimension information.
CONTEXT:  SQL statement "SELECT CAST(rightside as text[])"
PL/pgSQL function check_tag_matches(text[],text) line 4 at SQL statement
似乎当你尝试在
ANY()
中使用多维数组时,比如
array[array['a','M'],array['F','E'],array['E','R']]::text[]
ANY()
中,它不会迭代
数组['a','M']
,然后是
array['F','E']
,然后是
array['E','R'>,而是迭代
。使用
unest
时也会发生同样的情况

test=# SELECT unnest(ARRAY[ARRAY['A','M'], ARRAY['F','E'], ARRAY['E','R']]::text[][]);
 unnest 
--------
 A
 M
 F
 E
 E
 R
(6 rows)
剩下的选项a是定义一个函数,该函数将读取
array\u length(rightside,1)
array\u length(rightside,2)
,并使用嵌套循环检查所有内容,或者可以发送多个查询以获取每个标记的继承标记,或者以某种方式重新构造数据。你甚至不能使用
rightside[1]
访问
数组['A','M']
元素来迭代它,你不得不进入最深层次。

你可以试试

 SELECT * FROM table WHERE 
    tags @> ARRAY['A','C']::varchar[]
       OR
    tags @> ARRAY['E']::varchar[]
       OR
    tags @> ARRAY['F']::varchar[]
你可以试试

 SELECT * FROM table WHERE 
    tags @> ARRAY['A','C']::varchar[]
       OR
    tags @> ARRAY['E']::varchar[]
       OR
    tags @> ARRAY['F']::varchar[]

不幸的是,我们用来过滤行的二维数组是根据用户输入创建的,您的方法需要动态创建sql(对于不同的输入,我必须使用不同的sql),我们用于筛选行的二维数组是根据用户输入创建的,您的方法需要动态创建sql(对于不同的输入,我必须使用不同的sql)。PG多维数组支持非常差,如果可能,您应该重新考虑您的方法。我的意思是,忘记你发布的问题,只需执行
选择数组[ARRAY['A','C']::text[],ARRAY['F']::text[],ARRAY['E']::text[]::text[]::text[][
就会返回有关匹配维度的错误。PG多维数组的支持非常差,如果可能,你应该重新考虑你的方法。我的意思是,忘记你发布的问题,只需执行
选择数组[ARRAY['A','C']::text[],ARRAY['F']::text[],ARRAY['E']::text[]::text[]::text[][
返回有关匹配维度的错误。感谢你指出事实
多维数组要求每个子元素具有相同的长度。这表明我不能那样做。谢谢你指出事实
多维数组