2009-07-07 7 views
2

Je suis assez frais à la gestion de base de données, mais maintenant complètement sans expérience. Cependant, je suis coincé sur un problème. J'ai besoin de formuler une requête SQL qui retourne tous les articles compatibles à un ensemble d'autres articles (de taille arbitraire). La requête doit être générée par un script dans une application pour rechercher des articles dans lesquels l'utilisateur peut entrer une liste d'articles que tout article trouvé devrait utiliser (compatible).Article compatibilty dans la base de données SQL

Donc, pour une liste de numéros d'article A, B, ..., N, la question est:
"Donnez-moi tous les articles qui sont compatibles avec un et B et ... et N"

La question ne concerne qu'un seul tableau;
Compatible
ArtOne
artTwo

Chaque enregistrement compatible représente une relation de compatibilité afin que les articles A et B sont compatibles ssi il existe un enregistrement avec le numéro de l'article A dans une colonne et B dans l'autre . NB la commande ne fait aucune différence pour la compatibilité. Maintenant, vu une liste d'articles, je veux être capable de générer une requête qui retourne tous les articles qui sont compatibles.

Par exemple, considérons la table
Compatible

 
A B 
---- 
1 2 
3 1 
3 4 

Si je voulais tous les articles qui sont compatibles avec [1], la requête retournerait [2, 3].
La requête générée par la liste [2, 3] retournera [1].
Alors que la requête générée à partir de la liste [1, 3] génère une liste vide.

Certes, ce n'est probablement pas la meilleure façon de s'attaquer au problème, donc j'accueille aussi de meilleures solutions. Je pense que ce type de questions nécessite un certain type de sous-requêtes, un sujet que je suis encore à maîtriser. Donc, ma question est - Y at-il un moyen de modéliser la base de données afin que ce problème particulier soit résolu plus facilement, ou en tout cas, quelqu'un pourrait m'aider à formuler la requête et comment elle change avec la quantité variable d'entrée. Tout pointeur vers la lecture sur le sujet est également le bienvenu.

Un grand merci

Marco

+1

Définir la structure de la table et quel résultat vous voulez expliquer en détail – KuldipMCA

+0

d'accord, merci. OP modifié. – Nubsis

Répondre

1
SELECT id 
FROM (
     SELECT B AS id 
     FROM compat 
     WHERE A IN (list) 
     UNION 
     SELECT A 
     FROM compat 
     WHERE B IN (list) 
     ) q 
GROUP BY 
     id 
HAVING COUNT(*) = @cnt 

, où @cnt est le nombre total d'éléments dans votre liste. Pour que cela fonctionne, assurez-vous qu'aucune paire de compatibilité ne comporte deux entrées dans la table (par exemple, (1, 2) et (2, 1) est incorrect).

Il est préférable d'avoir deux contraintes: un veillant à ce que la paire est unique, l'autre en vérifiant que l'article le moins id être le premier:

ALTER TABLE compat ADD CONSTRAINT ux_compat_ab UNIQUE (A, B) 
ALTER TABLE compat ADD CONSTRAINT cc_compat_order CHECK (A < B) 

Si vous faites cela, vous pouvez remplacer UNION avec plus efficace UNION ALL:

SELECT id 
FROM (
     SELECT B AS id 
     FROM compat 
     WHERE A IN (list) 
     UNION ALL 
     SELECT A 
     FROM compat 
     WHERE B IN (list) 
     ) q 
GROUP BY 
     id 
HAVING COUNT(*) = @cnt 
+0

Cela a résolu parfaitement! Merci beaucoup! ---- Marco – Nubsis

0

select * de l'article une jointure compatTbl ct sur a.Id = ct.ArticleAID où ct.ArticleBID dans (liste des ids aller ici)

Questions connexes