2013-03-03 3 views
0

J'essaie d'énumérer user engagements unique avec le engagement_typeComment obtenir des engagements d'utilisateur uniques?

J'avais l'habitude d'avoir la question suivante.

SELECT u.id, u.fname, u.lname FROM (
    SELECT id, engagement_type FROM (
    SELECT user_id AS id, 'comment' 
    FROM comments WHERE commentable_id = 48136 AND commentable_type = 'Video' 
    UNION ALL 
    SELECT user_id AS id, 'like' 
    FROM likes WHERE likeable_id = 48136 AND likeable_type = 'Video' 
) AS a 
    GROUP BY id 
    LIMIT 10 
) b JOIN users u USING (id); 

Retours:

id  | fname  | lname 
------------------------------ 
1   | joe  | abc 
2   | sarah  | qer 
3   | megan  | tryey 
4   | john  | vdfa 

Ce qui est bien. Maintenant, je veux inclure le type d'engagement. Je suis venu avec ceci:

SELECT u.id, u.fname, u.lname, engagement_type FROM (
    SELECT id, engagement_type FROM (
    SELECT user_id AS id, 'comment' AS engagement_type 
    FROM comments WHERE commentable_id = 48136 AND commentable_type = 'Video' 
    UNION ALL 
    SELECT user_id AS id, 'like' AS engagement_type FROM likes 
    WHERE likeable_id = 48136 AND likeable_type = 'Video' 
) AS a 
    GROUP BY id, engagement_type 
    LIMIT 10 
) b JOIN users u USING (id); 

qui retourne maintenant:

id  | fname  | lname | engagement_type 
--------------------------------------------------- 
1   | joe  | abc  | comment 
2   | sarah  | qer  | like 
3   | megan  | tryey | like 
4   | john  | vdfa  | like 
1   | joe  | abc  | like  
3   | megan  | tryey | comment 

Le seul problème avec ci-dessus. Les résultats ne sont plus uniques. Comme vous pouvez le voir, Joe et Megan ont 2 entrées.

Une idée de comment je peux faire fonctionner ça?

+0

essayez de supprimer la clause 'engagement_type' de la clause' GROUP BY' et vérifiez si elle répond à vos besoins. – SparKot

+0

Cependant, 'joe' avait deux engagements uniques à savoir,' comment' & 'like'. C'est ainsi que "megan". – SparKot

+0

Cela dépend de ce que vous voulez faire. Voulez-vous afficher un seul type d'engagement ou une liste comme "comment, comme"? –

Répondre

1

Plus simple avec DISTINCT ON dans PostgreSQL.
Faute de définition Je choisis la première engagement_type selon son ordre de tri:

SELECT u.id, u.fname, u.lname, b.engagement_type 
FROM (
    SELECT DISTINCT ON (1) 
      id, engagement_type 
    FROM (
     SELECT user_id AS id, 'comment' AS engagement_type 
     FROM comments 
     WHERE commentable_id = 48136 
     AND commentable_type = 'Video' 

     UNION ALL 
     SELECT user_id, 'like' 
     FROM likes 
     WHERE likeable_id = 48136 
     AND likeable_type = 'Video' 
    ) a 
    ORDER BY 1, 2 
    LIMIT 10 
    ) b 
JOIN users u USING (id); 

Détails, liens et explication:

Si vous voulez une liste unique, de tous les types d'engagement:

string_agg() besoin de Postgres 9.0 ou plus tard.
Ce formulaire permet de commander par tout ce que vous voulez, alors que vous auriez besoin d'une autre sous-requête si vous voulez ORDER BY être en désaccord avec DISTINCT ON.

+0

Très belle solution. Appréciez-le! –

+0

Juste une chose comment fonctionne le «ORDER BY» ici? Et si je voulais commander par les engagements les plus récents? Comment pourrais-je m'y prendre? –

+0

@ChristianFazzini: Suivez le lien. J'ai écrit une explication détaillée à la réponse connexe qui devrait le couvrir. Commencez par définir "le plus récent". Il n'y a rien dans la question pour couvrir cela. –

0

Si vous ne voulez qu'une seule ligne, vous devez supprimer le type d'engagement de la clause GROUP BY. Cependant, cela ne vous montrera pas tous les différents types d'engagement.

Si vous souhaitez répertorier les types d'engagement dans une ligne sans dupliquer les détails de l'utilisateur, utilisez la fonction ARRAY_TO_STRING. Cela contamine les résultats sur une ligne. Vous pouvez donc lister les types d'engagement de la table des commentaires sous la forme d'une liste séparée par des virgules.

Questions connexes