Sorry for the nondescript title but I'm not sure how to phrase the question. Say we have the following tables:
people
id|created_at|updated_at|name |
--|----------|----------|-----------------|
1| | |Quentin Tarantino|
2| | |Terry O'Quinn |
3| | |Sam Jackson |
4| | |Michael Madsen |
5| | |Bryan Cranston |
crew_members
id|created_at|updated_at|type |
--|----------|----------|--------|
1| | |Actor |
2| | |Director|
3| | |Writer |
movies
id|created_at|updated_at|title |
--|----------|----------|--------------|
1| | |Pulp Fiction |
2| | |Reservoir Dogs|
series
id|created_at|updated_at|title |
--|----------|----------|------------------|
1| | |Lost |
2| | |Breaking Bad |
3| | |The Tarantino Show|
credits
id|created_at|updated_at|person_id|character |crew_member_id|
--|----------|----------|---------|------------|--------------|
1| | | 1| | 2|
2| | | 1|Jimmy | 1|
3| | | 1| | 3|
4| | | 2|John Locke | 1|
5| | | 3|Jules | 1|
6| | | 4|Mr Blonde | 1|
7| | | 5|Walter White| 1|
8| | | 1|Mr Brown | 1|
9| | | 1|Himself | 1|
credit_feature_person
id|created_at|updated_at|person_id|credit_id|movie_id|series_id|
--|----------|----------|---------|---------|--------|---------|
1| | | 1| 1| 1| 0|
2| | | 1| 2| 1| 0|
3| | | 1| 3| 1| 0|
4| | | 1| 1| 2| 0|
5| | | 1| 8| 2| 0|
6| | | 1| 3| 2| 0|
7| | | 2| 4| 0| 1|
8| | | 3| 5| 1| 0|
9| | | 4| 6| 2| 0|
10| | | 5| 7| 0| 2|
11| | | 1| 9| 0| 3|
If I want to show all movies a person (say, Tarantino with id 1) was involved in, plus what they did in that movie, I can do this:
select m.title as movie, coalesce(character,type) as role
from "credits"
inner join "credit_feature_person" on "credits"."id" = "credit_id"
inner join "people" on "credit_feature_person"."person_id" = "people"."id"
inner join "movies" m on "credit_feature_person"."movie_id" = "m"."id"
inner join "crew_members" on "credits"."crew_member_id" = "crew_members"."id"
where "credits"."person_id" = 1;
//result
movie | role
----------------+----------
Pulp Fiction | Director
Pulp Fiction | Jimmy
Pulp Fiction | Writer
Reservoir Dogs | Director
Reservoir Dogs | Mr Brown
Reservoir Dogs | Writer
(6 rows)
But I also want to include the series they worked on too, and the result to look like
title | role
----------------+----------
Pulp Fiction | Director
Pulp Fiction | Jimmy
Pulp Fiction | Writer
Reservoir Dogs | Director
Reservoir Dogs | Mr Brown
Reservoir Dogs | Writer
The Tarantino Show | Himself
(7 rows)
I keep trying different things and either get syntax errors or 0 results. Any ideas? I expected to at least be able to do this:
select coalesce(m.title, s.title) as title, coalesce(character,type) as role
from "credits"
inner join "credit_feature_person" on "credits"."id" = "credit_id"
inner join "people" on "credit_feature_person"."person_id" = "people"."id"
inner join "movies" m on "credit_feature_person"."movie_id" = "m"."id"
inner join "series" s on "credit_feature_person"."series_id" = "s"."id"
inner join "crew_members" on "credits"."crew_member_id" = "crew_members"."id"
where "credits"."person_id" = 1;
But this doesn't work either, it returns zero results for some reason.
Edit: Solution is to use left joins on movies and series
select coalesce(m.title,s.title) as title, coalesce(character,type) as role
from "credits"
inner join "credit_feature_person" on "credits"."id" = "credit_id"
inner join "people" on "credit_feature_person"."person_id" = "people"."id"
left join "movies" m on "credit_feature_person"."movie_id" = "m"."id"
left join "series" s on "credit_feature_person"."series_id" = "s"."id"
inner join "crew_members" on "credits"."crew_member_id" = "crew_members"."id"
where "credits"."person_id" = 1;
The problem is that the links to movies and series are mutually exclusive. When you attempt an inner join to the one side that's missing each of the rows is eliminated from the results. Those two joins need to be left outer joins.
select coalesce(m.title, s.title) as title, coalesce(character,type) as role
from "credits"
inner join "credit_feature_person" on "credits"."id" = "credit_id"
inner join "people" on "credit_feature_person"."person_id" = "people"."id"
inner join "crew_members" on "credits"."crew_member_id" = "crew_members"."id"
left outer join "movies" m on "credit_feature_person"."movie_id" = "m"."id"
left outer join "series" s on "credit_feature_person"."series_id" = "s"."id"
where "credits"."person_id" = 1
order by title, role;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.