Sql 在复合类型数组中搜索元素

Sql 在复合类型数组中搜索元素,sql,arrays,postgresql,Sql,Arrays,Postgresql,使用PostgreSQL 9.0 我有下面的表格设置 CREATE TABLE person (age integer, last_name text, first_name text, address text); CREATE TABLE my_people (mperson person[]); INSERT INTO my_people VALUES(array[ROW(44, 'John', 'Smith', '1234 Test Blvd.')::person]); 现在,我希

使用PostgreSQL 9.0

我有下面的表格设置

CREATE TABLE person (age integer, last_name text, first_name text, address text);

CREATE TABLE my_people (mperson person[]);

INSERT INTO my_people VALUES(array[ROW(44, 'John', 'Smith', '1234 Test Blvd.')::person]);
现在,我希望能够编写一个select语句,在我的mperson数组列中搜索和比较我的复合类型的值

例如:

SELECT * FROM my_people WHERE 20 > ANY( (mperson) .age);
但是,在尝试执行此查询时,我遇到以下错误:

ERROR:  column notation .age applied to type person[], which is not a composite type
LINE 1: SELECT mperson FROM my_people WHERE 20 > ANY((mperson).age);
因此,您可以看到我正在尝试测试数组中复合类型的值

我知道,我不应该在我的表中使用数组和组合,但这最适合我们的应用程序需求


另外,我们有几个嵌套的复合阵列,因此,如果能提供一个通用的解决方案,使我能够搜索多个级别,我们将不胜感激。

在您的情况下,任何构造看起来都是多余的。您可以这样编写查询:

SELECT * FROM my_people WHERE (mperson[1]).age < 20;
从my_people中选择*,其中(mperson[1])。年龄<20岁;
当然,如果您在这个数组中有多个值,这将不起作用,但是您也无法通过另一种方式获得确切的数组元素

为什么需要阵列?每行只能写一个person类型的元素

同时检查优秀模块,它可能更适合您的一般需求。

临时测试设置:

CREATE TEMP TABLE person (age integer, last_name text, first_name text
                                                     , address text);
CREATE TEMP TABLE my_people (mperson person[]);

-- test-data, demonstrating 3 different syntax styles:
INSERT INTO my_better_people (mperson)
VALUES
   (array[(43, 'Stack', 'Over', '1234 Test Blvd.')::person])

  ,(array['(44,John,Smith,1234 Test Blvd.)'::person,
          '(21,Maria,Smith,1234 Test Blvd.)'::person])

  ,('{"(33,John,Miller,12 Test Blvd.)",
      "(22,Frank,Miller,12 Test Blvd.)",
      "(11,Bodi,Miller,12 Test Blvd.)"}');
调用(几乎就是解决方案):

返回:

 age | last_name | first_name |     address
-----+-----------+------------+-----------------
  43 | Stack     | Over       | 1234 Test Blvd.
  44 | John      | Smith      | 1234 Test Blvd.
  • 关键是关键
  • 您在示例中的错误是忘记了中间的数组层
    unnest()
    为每个基本元素返回一行,然后您可以访问复杂类型中的列,如图所示

勇敢的新世界 如果您确实想要一个符合标准的整体而不是个人,我建议您在表中添加一个主键,并按如下步骤进行操作:

CREATE TEMP TABLE my_better_people (id serial, mperson person[]);

-- shortcut to populate the new world by emigration from the old world ;)
INSERT INTO my_better_people (mperson)
SELECT mperson FROM my_people;
查找个人:

SELECT id, (p).*
FROM  (
   SELECT id, unnest(mperson) AS p
   FROM   my_better_people) x
WHERE  (p).age > 20;
找到全体员工(解决方案):

  • 您可以在没有主键的情况下执行此操作,但那将是愚蠢的

I固定
在设置中插入
SELECT id, (p).*
FROM  (
   SELECT id, unnest(mperson) AS p
   FROM   my_better_people) x
WHERE  (p).age > 20;
SELECT *
FROM   my_better_people p
WHERE  EXISTS (
   SELECT 1 
   FROM (
      SELECT id, unnest(mperson) AS p
      FROM   my_better_people
      ) x
   WHERE  (p).age > 20
   AND    x.id = p.id
   );