2010-06-27 5 views
0

J'ai trois tables:SQL comment sélectionner toutes les lignes liées à des conditions externes

player [id, name] 
attribute [id, name] 
player_attribute [id, player_id, attribute_id, value] 

chaque joueur peut avoir des attributs différents, certains d'entre eux n'avez pas encore. Maintenant, je dois rechercher des joueurs avec certains attributs, par ex. tous les joueurs qui ont le numéro 11, et leur prénom est John. En ce moment, je sais aussi id de ces attributs, where partie de ma requête peut ressembler à: WHERE (attribute.id, attribute.value) in ((5, '11'), (18, 'John'))

Je dois obtenir tous les joueurs qui répond à tous les attributs demandés.

Le problème est que je ne sais pas à quoi doit ressembler toute la requête? J'ai essayé les jointures, les sélections imbriquées, le regroupement mais je ne suis pas capable de le faire fonctionner. Je reçois toujours trop, ou pas assez de lignes.

Pouvez-vous m'aider s'il vous plaît?

EDIT Merci à aranid que j'ai trouvé une solution:

select player_id from (
    select * from player_attribute where (attribute.id, attribute.value) in ((5, '11'), (18, 'John'))) 
group by player_id 
having count(*) = 2 

donc, le mot-clé a été having by utilisé correctement :)
Est-il possible de transformer ci-dessus requête dans JOIN déclaration?

+1

Ce genre de question se reproduit raisonnablement souvent, vous pouvez trouver l'inspiration supplémentaire dans http://stackoverflow.com/questions/3102362/sql-how-do-i-make-a-selection-based-on-categories par exemple . – araqnid

+0

merci araqnid! J'ai trouvé quelques indices, j'ai édité ma question pour inclure une réponse – uolot

+0

J'ai ajouté la balise 'eav' mais j'ai dû cannibaliser la balise' select' que vous avez utilisée, car il y a une limite de cinq balises. Je pensais que 'select' était superflue après' sql' et 'query'. –

Répondre

2

J'espère avoir bien compris votre question. Cela devrait retourner tous les player_id s qui ont un attribut (5, '11') et l'autre avec (18, 'John'):

Select a1.player_id 
From player_attribute a1 
Join player_attribute a2 On (a2.player_id = a1.player_id) 
Where a1.attribute_id = 5 And a1.value = '11' 
    And a2.attribute_id = 18 And a1.value = 'John' 

Une raison particulière pour ne pas stocker ces attributs dans la table player?

player (id, first_name, last_name, player_number, ...) 

Cela rendrait ces requêtes beaucoup plus facile

Select id 
From player 
Where first_name = 'John' And player_number = 11 
+0

bien, cela fonctionne, mais le problème est, et si j'ai besoin de chercher 3 attributs, ou 10, ou plus? De plus, les attributs ne sont pas stockés dans la table des joueurs, car ils sont définis par l'utilisateur final et je ne sais pas combien et quel type d'attributs seront nécessaires – uolot

2

Vous utilisez la conception Entité-attribute-value, ce qui est juste pour une quelconque base de données relationnelle.

Vous seriez probablement plus heureux en utilisant l'une des nouvelles bases de données non relationnelles telles que CouchDB ou MongoDB. Ce sont les bases de données orientées document , conçues pour exactement le scénario que vous avez, où les utilisateurs peuvent définir leurs propres attributs et vous ne connaissez pas les attributs au moment où vous concevez la base de données.

+0

merci pour vos conseils. les tableaux que j'ai utilisés ici ne sont qu'un exemple, le projet sur lequel je travaille est assez important en ce moment et j'ai besoin de ces attributs dans une petite partie, donc passer à une autre DB n'est pas possible. Merci quand même! – uolot

+0

L'utilisation d'un HSTORE, http://www.postgresql.org/docs/8.4/static/hstore.html, dans Postgres offre de nombreux avantages similaires à ceux des schémas non-relationnels. – rfusca

Questions connexes