2017-08-25 5 views
0

Il y a beaucoup de variations de requêtes acteur/films. Et je ne peux pas trouver l'approche correcte, en essayant de choisir des colonnes non-groupe: J'ai 3 tables film (film_id, titre), acteur (acteur, prénom, nom de famille), film_actor (acteur, film_id). Donc, j'ai besoin de trouver 2 acteurs, qui jouent ensemble le plus et montrent la sortie comme actor1_last_name, actor2_last_name, film_title pour les 5 premiers films. Ce que je fais est d'abord, l'apparence de comptage des acteurs:sql sélectionner les acteurs jouent ensemble

select r1.actor_id as actor_a, r2.actor_id as actor_b, 
count(r1.film_id) as casted_together 
from film_actor r1 inner join film_actor r2 on r1.film_id = r2.film_id 
and r1.actor_id > r2.actor_id 
group by r1.actor_id, r2.actor_id 
order by casted_together desc 

Cela me retourne table comme

actor_a | actor_b| casted_together 
Name  Name  7 
...  ...  6 

Mais une fois que j'essaie d'ajouter film.title pour le sélectionner dit que je peux » t l'utiliser dans le cas où il n'est pas dans la section groupe ((select title from film where film_id = r1.film_id) as film_title). Comment puis-je utiliser les résultats du regroupement ci-dessus et y ajouter une colonne externe? Dans mon cas, c'est film.title.

sortie souhaitée:

actor_a_last_name | actor_b_last_name| film_title 
Name    Name    Title 
...     ...     ... 

Say, George Clooney et Pain Pitt ont le plus grand nombre de films ensemble (9) et le résultat devrait montrer les premiers 5 9 lignes

actor_a_last_name | actor_b_last_name| film_title 
    Clooney    Pitt   Film 1 
    Clooney    Pitt   Film 2 
    ...     ...    ... 
+0

Pouvez-vous partager la sortie désirée – Shuddh

Répondre

1

Utilisez une agrégat, par exemple string_agg() ou array_agg():

select 
    r1.actor_id as actor_a, 
    r2.actor_id as actor_b, 
    count(r1.film_id) as casted_together, 
    string_agg(f.title, ', ') as films 
from film_actor r1 
join film_actor r2 
    on r1.film_id = r2.film_id 
    and r1.actor_id > r2.actor_id 
join film f 
    on r1.film_id = f.film_id 
group by r1.actor_id, r2.actor_id 
order by casted_together desc 

Utilisez la requête comme une table dérivée et ajouter les noms des acteurs et un titre de film:

select 
    a1.last_name, 
    a2.last_name, 
    f.title 
from (
    select 
     r1.actor_id as actor_a_id, 
     r2.actor_id as actor_b_id, 
     count(r1.film_id) as casted_together, 
     array_agg(r1.film_id) as film_ids 
    from film_actor r1 
    join film_actor r2 
     on r1.film_id = r2.film_id 
     and r1.actor_id > r2.actor_id 
    join film f 
     on r1.film_id = f.film_id 
    group by r1.actor_id, r2.actor_id 
    order by casted_together desc 
    limit 1 
    ) s 
join actor a1 on a1.actor_id = s.actor_a_id 
join actor a2 on a2.actor_id = s.actor_b_id 
join film f on f.film_id = any(s.film_ids) 
+0

Klin, il retourne simplement la liste de tous les films possibles , mais j'ai encore besoin de 'trouver 2 acteurs, qui jouent ensemble le plus et montrent la sortie comme actor1_last_name, actor2_last_name, film_title pour les 5 premiers films de ce type, donc group_by devrait être ici définitivement – Stan

+0

Utilisez la première requête et ajoutez-y les jointures à l'acteur et filmer comme dans le second. Voir la réponse mise à jour. – klin

+0

'array_agg' fonctionne tout simplement génial. Je vous remercie – Stan