It looks like there is a Many to Many relationship between stars_in_movies and genres_in_movies. You need to perform your query step by step. First create a sub-query that groups on movies JOIN genres_in_movies. Then create a second sub query that groups on movies JOIN stars_in_movies. Then join between the sub queries on movie.id. This way you have a one to one relationship between the sub queries and you avoid the cartesian product that you currently have.
Grouping row on column and flattening the other columns
-
04-10-2022 - |
Domanda
I have the following schema:
TABLE ATTRIBUTES
---------------------------
movies id
title
stars id
first_name
last_name
genres id
name
stars_in_movies movie_id
star_id
genres_in_movies movie_id
genre_id
I want to create a query that returns a view that is grouped by movie.id
and that concatenates the list of associated stars
and genres
This is my attempt:
SELECT movies.id, title,
GROUP_CONCAT(stars.id separator ',') AS starIds,
GROUP_CONCAT(concat(first_name,' ',last_name) separator ',') AS starNames,
GROUP_CONCAT(genres.id separator ',') AS genreIds,
GROUP_CONCAT(genres.name separator ',') AS genreNames
FROM movies
JOIN stars_in_movies ON stars_in_movies.movie_id = movies.id
JOIN stars ON stars_in_movies.star_id = stars.id
JOIN genres_in_movies ON genres_in_movies.movie_id = movies.id
JOIN genres ON genres_in_movies.genre_id = genres.id
For some reason, for each row in the view, the query concatenates the same star for each genre. For example here is an example of a row:
movie.id movie.title stars.id genres.id
-----------------------------------------------------------
12345 Ocean's Twelve 3,3,3,4,4,4 2,4,6,2,4,6,2,4,6
EDIT:
This is the result of the query without using GROUP_CONCAT
. It lists all combinations of tuples.
SELECT movies.id, stars.id, genres.id FROM movies
JOIN stars_in_movies ON stars_in_movies.movie_id = movies.id
JOIN stars ON stars_in_movies.star_id = stars.id
JOIN genres_in_movies ON genres_in_movies.movie_id = movies.id
JOIN genres ON genres_in_movies.genre_id = genres.id
WHERE movies.title = 'Oceans Twelve';
+--------+--------+--------+
|movies.id|stars.id|genres.id|
+--------+--------+--------+
| 764010 | 492108 | 907000 |
| 764010 | 492108 | 907001 |
| 764010 | 492108 | 855203 |
| 764010 | 492108 | 907002 |
| 764010 | 492108 | 150008 |
| 764010 | 492108 | 907005 |
| 764010 | 48004 | 907000 |
| 764010 | 48004 | 907001 |
| 764010 | 48004 | 855203 |
| 764010 | 48004 | 907002 |
| 764010 | 48004 | 150008 |
| 764010 | 48004 | 907005 |
| 764010 | 48014 | 907000 |
| 764010 | 48014 | 907001 |
| 764010 | 48014 | 855203 |
| 764010 | 48014 | 907002 |
| 764010 | 48014 | 150008 |
| 764010 | 48014 | 907005 |
| 764010 | 855108 | 907000 |
| 764010 | 855108 | 907001 |
| 764010 | 855108 | 855203 |
| 764010 | 855108 | 907002 |
| 764010 | 855108 | 150008 |
| 764010 | 855108 | 907005 |
| 764010 | 658011 | 907000 |
| 764010 | 658011 | 907001 |
| 764010 | 658011 | 855203 |
| 764010 | 658011 | 907002 |
| 764010 | 658011 | 150008 |
| 764010 | 658011 | 907005 |
| 764010 | 855106 | 907000 |
| 764010 | 855106 | 907001 |
| 764010 | 855106 | 855203 |
| 764010 | 855106 | 907002 |
| 764010 | 855106 | 150008 |
| 764010 | 855106 | 907005 |
| 764010 | 693109 | 907000 |
| 764010 | 693109 | 907001 |
| 764010 | 693109 | 855203 |
| 764010 | 693109 | 907002 |
| 764010 | 693109 | 150008 |
| 764010 | 693109 | 907005 |
+--------+--------+--------+
Soluzione
Altri suggerimenti
Add GROUP BY movies.id, title to the query.
Your query is ALMOST correct, you just need to add another grouping (in order those IDs to be unique in concatenation): by movies.id
, stars.id
and genres.id
:
/* YOUR QUERY */
GROUP BY movies.id, stars.id, genres.id
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow