Reputation: 538
I have a table:
id integer
status_id integer
children integer[]
How do I write a query to join the table to itself on children and find all records where (all children items have status_id 2) & the item has status of 1?
In addition should children be indexed and with what index?
Edit: Based on krokodilko answer I think the query may be:
SELECT id
FROM (
SELECT p.id, p.status_id, every(c.status_id = 2) AS all_children_status_2
FROM positions p
JOIN positions c
ON c.id = ANY (p.children)
GROUP BY p.id, p.status_id
) sub
WHERE all_children_status_2 IS TRUE AND status_id = 1;
Edit 2: Please note I have found in my reading that the array columns should use a GIN or GIST index. However unfortunately postgres does not use these indexes when using ANY. These mean that while the above query works it is very slow.
Upvotes: 1
Views: 1742
Reputation: 36127
Use ANY operator:
Demo: http://www.sqlfiddle.com/#!17/2540d/1
CREATE TABLE parent(
id int,
child int[]
);
INSERT INTO parent VALUES(1, '{2,4,5}');
CREATE TABLE child(
id int
);
INSERT INTO child VALUES (1),(2),(3),(4),(5);
SELECT *
FROM parent p
JOIN child c
ON c.id = any( p.child );
| id | child | id |
|----|-------|----|
| 1 | 2,4,5 | 2 |
| 1 | 2,4,5 | 4 |
| 1 | 2,4,5 | 5 |
In addition should children be indexed and with what index?
Yes - if children table is huge (more than a few hundreds/thousands rows).
CREATE INDEX some_name ON child( id )
Upvotes: 1