Requête SQL sur des valeurs d'attributs d'un objet

Requête SQL sur des valeurs d'attributs d'un objet - SQL/NoSQL - Programmation

Marsh Posté le 23-08-2006 à 17:14:46    

Bonjour,
 
j'aurais voulu connaître la meilleure requête SQL permettant de rechercher des objets via des valeurs de leurs attributs. Je m'explique :
j'ai un ordinateur (calculateur, pour être précis). Celui-ci est composé de composants. Chaque composant est composé d'attributs ayant un ID, un nom et une valeur sous la forme de chaîne.
Ex :  
Ordi_1 (1)
  +----CPU (1)
  |        +---Fréquence = 2 Ghz (1)
  |        +---Modèle = AMD (2)
  +---HDD (2)
           +---Modèle = Maxtor (3)
           +---Capacité = 146 Go (4)
           +---Firmware = 1354 (5)
 
Donc dans ma table "ordi-cmp" faisant le lien entre l'ordi et ses composants j'ai :  
+----+--------+-------+
| ID  |  IDordi  | IDcmp |
+----+--------+-------+
| 1   |    1       |    1    |
| 2   |    1       |    2    |
+----+--------+-------+
 
Dans ma table "cmp-attr" faisant le lein entre le composant et ses attributs j'ai :  
+----+--------+-------+
| ID  |  IDcmp  | IDattr |
+----+--------+-------+
| 1   |    1       |    1    |
| 2   |    1       |    2    |
| 3   |    2       |    3    |
| 4   |    2       |    4    |
| 5   |    2       |    5    |
+----+--------+-------+
 
Enfin, dans ma table "attributs", j'ai :
+----+-----------+--------+
| ID  |  Nom         | Valeur  |  
+----+-----------+--------+
| 1   | Fréquence  | 2 GHz   |
| 2   | Modèle       | AMD    |
| 3   | Modèle       | Maxtor |
| 4   | Capacité    | 146 Go |
| 5   | Firmware    |  1354   |
+----+-----------+--------+
 
Je souhaiterais pouvoir créer un petit moteur de recherche où je demanderais "trouves-moi les ordis qui ont des attributs ayant pour valeur 'AMD' ET '146 Go' ET...ET etc...", le nombre de ET étant variable
En SQL, comme se traduit ce genre de requête??? Merci de votre aide.
 

Reply

Marsh Posté le 23-08-2006 à 17:14:46   

Reply

Marsh Posté le 23-08-2006 à 21:53:16    

En reprenant le problème calmement et méthodiquement, devrait pas y avoir de difficulté pour construire la requête :)  
On part des attributs :
 
FROM attribus A
WHERE (
    (A.Nom="Nom_1" AND A.Valeur="Val_1" )
OR (A.Nom="Nom_2" AND A.Valeur="Val_2" )
...
)
 
Pas très difficile à construire depuis un formulaire rempli par l'utilisateur :)  
Là, on les attributs recherchés, on peut remonter vers l'ordi. D'abord par la table cmp-attr :
FROM attribus A, cmp-attr CA
WHERE (
    (Nom="Nom_1" AND Valeur="Val_1" )
OR (Nom="Nom_2" AND Valeur="Val_2" )
...
) AND (
    A.ID = CA.IDattr
)

(certains préfèreraient peut être un LEFT JOIN [:figti] )
 
Puis on y ajoute la table ordi-cmp :
FROM attribus A, cmp-attr CA, ordi-cmp OC
WHERE (
    (Nom="Nom_1" AND Valeur="Val_1" )
OR (Nom="Nom_2" AND Valeur="Val_2" )
...
) AND (
    CA.IDattr = A.ID
) (
    OC.IDcmp = CA.IDcmp
)

 
Là, on tu as toutes les infos, tu n'as plus qu'à y mettre le SELECT qui t'intéresse (par exemple, un SELECT DISTINCT ordi-cmp.IDordi pour ne récupérer que les ID des PC qui correspondent) :)


Message édité par mrbebert le 23-08-2006 à 21:54:21
Reply

Marsh Posté le 24-08-2006 à 10:51:03    

Sauf que cette requête n'est pas correcte à 100% à cause du OR. En effet, un calculateur qui aurait seulement (Nom="Nom_1" AND Valeur="Val_1" ) va être remonté aussi. Moi, je veux avoir uniquement les calculateurs qui ont tous les attributs saisis par l'utilisateur.
 
Moi, j'avais en tête une requête bien bourrin où on fait autant de jointures sur la table Attributs qu'il y a d'attributs utilisés pour la recherche :
FROM cmp-attr CA, Attributs A1, Attributs A2, ... Attributs An WHERE (CA.IDAttr = A1.ID AND A1.Nom="Nom_1" AND A1.Valeur="Val_1" ) AND
(CA.IDAttr = A2.ID AND A2.Nom="Nom_2" AND A2.Valeur="Val_2" ) AND...(CA.IDAttr = An.ID AND An.Nom="Nom_n" AND An.Valeur="Val_n" )
 
Ca doit marcher je pense, mais bonjour l'élégence et al lourdeur de la requête :/


Message édité par rufo le 24-08-2006 à 15:27:40
Reply

Marsh Posté le 24-08-2006 à 15:27:47    

y'a pas mieux?

Reply

Marsh Posté le 24-08-2006 à 15:29:03    

dans le principe, non

Reply

Marsh Posté le 24-08-2006 à 16:22:20    

ah? :( comme quoi être bourrin, y'a que ça de vrai :lol:
Je vais voir si avec des sous-requêtes et les clauses IN et ALL, on peu pas faire mieux...

Reply

Marsh Posté le 25-08-2006 à 17:24:00    

up...

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed