Given the following sql table
| id | name | mother | father | brothers |
|----|-------|--------|--------|-----------|
| 1 | danny | 3 | 2 | {4, 6, 7} |
| 2 | bob | 20 | 30 | {} |
| 3 | marge | 10 | 50 | {} |
| 4 | rose | 3 | 2 | {1, 6, 7} |
I want to get the names of the siblings of danny (id: 1).
I can do it with 2 queries and the help of programming language, making 1 query like
SELECT mother, father, brothers
FROM people
WHERE id = 1
then process it and do
SELECT name
FROM people
where id IN (3, 2, 4, 6, 7)
but I wonder if I could achieve the same result with a single query.
Edit:
In this example there are "just" 3 fields, I will be having around 15 of these fields in the real use scenario.
I found that I can do
SELECT "name"
FROM people
WHERE id IN
(
SELECT mother AS sibling
FROM people
WHERE id = 1
UNION
SELECT Unnest(brothers) AS sibling
FROM people
WHERE id = 1)
is that the most effective way? performance wise it doesn’t seem efficient since every union runs the same query again and again. Unless under the hood postgres knows how to optimize it.
Also this query involve lot of repeating of the from and where.
2
Answers
Something like this would probably work:
You could obviously enhance this to retrieve the columns you want, remove duplicated, etc.
Related:
If
father
andmother
are always known, you best drop the redundant columnbrothers
(which should be called "siblings"). Then the query could be:In a gender-fluid world, check more thoroughly:
Either query returns people without siblings, too.
And neither duplicates siblings. (In the first case, the list strictly represents the
brothers
array.fiddle