2010-01-05 15 views
1

J'ai une base de données MySQL avec plusieurs tables dont les enregistrements peuvent être étiquetés, donc j'ai une table tags, et une table tag_associations qui relie les balises à d'autres tables "taggable" via plusieurs clés étrangères, et aussi à un "possédante" utilisateur - mes champs sont quelque chose comme ce qui suit:Comptage des enregistrements d'une table avec plusieurs clés étrangères (MySQL)

  • tag_association_id (clé primaire)
  • user_id (tag créateur d'association)
  • tag_id (étiquette liée)
  • artist_id (identifié rtist, peut être nul)
  • album_id (album marqué, peut être null)
  • track_id (piste marquée peut être nul)

Je veux essentiellement compter tous les éléments qui ont été marqués d'une étiquette particulière - si quelque chose le long des résultats de cette requête:

SELECT 
    COUNT(ta.tag_association_id) AS how_many 
FROM 
    tag_associations AS ta 
    LEFT JOIN users AS u ON ta.user_id = u.user_id 
WHERE 
    ta.tag_id = '480' 
    AND u.user_status = 'active' 

Mais le problème avec cette requête se trouve dans les cas où la même étiquette a été appliquée au même élément par plusieurs utilisateurs, donc si 2 utilisateurs différents tag l'artiste 'Bobby Jones Band' en tant que 'rad', il compte les deux associations de balises où je veux juste le compter une fois. J'ai essayé d'ajouter ceci à ce qui précède:

GROUP BY ta.artist_id, ta.album_id, ta.track_id 

... qui m'a près, mais n'a pas donné les résultats exacts que je avais besoin - il m'a donné plusieurs résultats de ligne de différents chefs d'accusation. Y a-t-il de la magie que je peux utiliser dans un cas comme celui-ci et le garder dans une seule requête? Tout en restant aussi efficace que possible, bien sûr :) Merci!

Répondre

1

Si j'ai bien compris votre question, alors votre GROUP BY devrait presque faire le travail.

Cette solution doit obtenir les lignes uniques de tag_associations et les compter.

SELECT COUNT(*) 
FROM 
(
    SELECT 1 
    FROM tag_associations AS ta 
    LEFT JOIN users AS u ON ta.user_id = u.user_id 
    WHERE ta.tag_id = '480' 
    AND u.user_status = 'active' 
    GROUP BY ta.artist_id, ta.album_id, ta.track_id 
) x 
+0

Merci pour la réponse Peter! Quand j'exécute ceci, j'obtiens une erreur: "Chaque table dérivée doit avoir son propre alias". Il me semble que les résultats de la sous-requête sont utilisés dans le FROM, et donc que la table est interrogée dans la requête externe - est-ce exact? Dans ce cas, il est logique que les résultats ne viennent pas si ... –

+0

Désolé. J'ai ajouté l'alias ('x'), veuillez réessayer. –

+0

Ah ça l'a fait, merci! –

Questions connexes