使用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);
所以,你可以看到我正在尝试测试我的数组中复合类型的值。
我知道,我不应该在我的表格中使用数组和复合材料,但这最符合我们的应用程序要求。
此外,我们有几个嵌套的复合数组,因此我们可以理解允许我搜索多个级别的通用解决方案。
答案 0 :(得分:2)
您的案例中的结构ANY看起来多余。您可以通过以下方式编写查询:
SELECT * FROM my_people WHERE (mperson[1]).age < 20;
当然,如果你在这个数组中有多个值,那将无法工作,但你也无法以其他方式获得确切的数组元素。
为什么你需要阵列?你可以在每行写一个person类型的元素。
还要检查优秀的HStore模块,它可能更适合您的通用需求。
答案 1 :(得分:2)
临时测试设置:
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.)"}');
致电(几乎解决方案):
SELECT (p).*
FROM (
SELECT unnest(mperson) AS p
FROM my_people) x
WHERE (p).age > 33;
返回:
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;
找到所有人(解决方案):
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
);