faire une liste d'exclusion en sql

faire une liste d'exclusion en sql - SQL/NoSQL - Programmation

Marsh Posté le 07-08-2004 à 15:33:29    

hello la compagnie,
 
est ce qu'un mordu de sql (mysql) pourrait me donner 2 ou 3 tuyaux sur l'exam suivant :  :(  
 
voici l'énoncé du problème, j'ai passé 3 jours et je bug toujours  :fou:  
------
- Une usine construit des voitures de marques différentes dans un pays donné
- cette usine ne construit pas une exception de marques
- l'usine ne construit que les voitures de son pays
>>> comment faire la liste des voitures d'une usine donnée
------
 
J'ai donc posé mes tables comme suit:
- 1 table usine(nom,pays)
- 1 table voitures(marque,pays)
- 1 table exclusion(usine,marque)
 
voici un export de la base
 

Code :
  1. # --------------------------------------------------------
  2. #
  3. # Structure de la table `exclusion`
  4. #
  5. CREATE TABLE `exclusion` (
  6.   `usine` char(1) NOT NULL default '',
  7.   `marque` varchar(10) NOT NULL default ''
  8. ) TYPE=MyISAM;
  9. #
  10. # Contenu de la table `exclusion`
  11. #
  12. INSERT INTO `exclusion` (`usine`, `marque`) VALUES ('A', 'peugeot');
  13. INSERT INTO `exclusion` (`usine`, `marque`) VALUES ('A', 'renault');
  14. INSERT INTO `exclusion` (`usine`, `marque`) VALUES ('C', 'GOLF');
  15. # --------------------------------------------------------
  16. #
  17. # Structure de la table `usine`
  18. #
  19. CREATE TABLE `usine` (
  20.   `nom` char(1) NOT NULL default '',
  21.   `pays` char(2) NOT NULL default ''
  22. ) TYPE=MyISAM;
  23. #
  24. # Contenu de la table `usine`
  25. #
  26. INSERT INTO `usine` (`nom`, `pays`) VALUES ('A', 'FR');
  27. INSERT INTO `usine` (`nom`, `pays`) VALUES ('B', 'FR');
  28. INSERT INTO `usine` (`nom`, `pays`) VALUES ('C', 'DE');
  29. INSERT INTO `usine` (`nom`, `pays`) VALUES ('D', 'DE');
  30. # --------------------------------------------------------
  31. #
  32. # Structure de la table `voitures`
  33. #
  34. CREATE TABLE `voitures` (
  35.   `marque` varchar(10) NOT NULL default '',
  36.   `pays` char(2) NOT NULL default ''
  37. ) TYPE=MyISAM;
  38. #
  39. # Contenu de la table `voitures`
  40. #
  41. INSERT INTO `voitures` (`marque`, `pays`) VALUES ('peugeot', 'FR');
  42. INSERT INTO `voitures` (`marque`, `pays`) VALUES ('renault', 'FR');
  43. INSERT INTO `voitures` (`marque`, `pays`) VALUES ('citroen', 'FR');
  44. INSERT INTO `voitures` (`marque`, `pays`) VALUES ('bmw', 'DE');
  45. INSERT INTO `voitures` (`marque`, `pays`) VALUES ('golf', 'DE');


 
et voici une requete exemple de la mort qui tue  :pt1cable:  
pour l'usine 'A':

Code :
  1. SELECT  voitures.marque, usine.pays,
  2. usine.nom as usine, exclusion.marque as marque_que_cette_usine_ne_construit_pas
  3. FROM voitures
  4. RIGHT JOIN usine ON usine.pays = voitures.pays
  5. LEFT JOIN exclusion ON exclusion.usine = usine.nom
  6. WHERE usine.nom = 'A'


 
Dont voici le résultat:
http://www.tsenagasy.com/requete.jpg
 
On s'aperçoit qu'il manque la condition d'exclusion, il faut complètement exclure renault et peugeot de la liste  :fou:  
 
J'ai rajouté à la fin de la requete
AND exclusion.marque != voitures.marque
 
Mais voici ce que ça donne:
http://www.tsenagasy.com/requete2.jpg
 
Dans la liste on retrouve toujours RENAULT alors qu'on sait que l'usine A ne construit pas de RENAULT (ligne 3 et 4)
Idem pour PEUGEOT !
Je pense qu'il faut faire un (OR) mais je ne sais pas où...
 
 :heink:  :fou:


Message édité par dapp le 07-08-2004 à 15:35:12
Reply

Marsh Posté le 07-08-2004 à 15:33:29   

Reply

Marsh Posté le 07-08-2004 à 15:36:03    

ou un autre AND mais quelle condition ?-/

Reply

Marsh Posté le 07-08-2004 à 15:57:06    

moi je verrais bien ca comme tables :
 
Factory (Factory_Id, Country_Id) Factory_Id en PK
 
Country (Country_Id, Country_Label) Country_Id en PK
 
Exception (Factory_Id, Brand_Id) : Factory_Id & Brand_Id en PK, Brand_Id en FK
 
Brand (Brand_Id, Brand_Label, Country_Id) : Brand_Id en PK, Country_Id en FK


---------------
Hobby eien /人◕ ‿‿ ◕人\
Reply

Marsh Posté le 07-08-2004 à 16:44:56    

et la requete ?
 
je ne vois pas comment on crée une foreign key en mysql :-/

Reply

Marsh Posté le 07-08-2004 à 17:29:34    

Si on t'as donné un énoncé tel que tu nous le transmets, ton professeur doit retourner prendre des cours de français et de logique. Il manque des données à ce problème.


Message édité par gizmo le 07-08-2004 à 17:29:57
Reply

Marsh Posté le 07-08-2004 à 20:57:01    

dapp a écrit :

et la requete ?
 
je ne vois pas comment on crée une foreign key en mysql :-/


 
j'sais pas non plus, j'utilise que des vrais sgbd... [:spamafote]
 
quant à la requete c'est qd meme pas bien compliqué, non ?


---------------
Hobby eien /人◕ ‿‿ ◕人\
Reply

Marsh Posté le 07-08-2004 à 21:30:43    

gizmo a écrit :

Si on t'as donné un énoncé tel que tu nous le transmets, ton professeur doit retourner prendre des cours de français et de logique. Il manque des données à ce problème.


 
je le dis comme ça mais c'est pas du copier/coller hein  :)  
 
Tamahome a bien compris le probleme, mais en mysql il n'y a pas de clés étrangères donc je ne vois pas comment on peut faire.

Reply

Marsh Posté le 07-08-2004 à 23:34:56    

tu peux ptet pas les mettre, elles sont ptet implicites... tu peux pas mettre de contrainte d'intégrité en mySQL ? m'etonne ca qd meme...


---------------
Hobby eien /人◕ ‿‿ ◕人\
Reply

Marsh Posté le 08-08-2004 à 00:33:12    

si, j'ai trouvé, mais c'est la requete qui m'importe:
comment avoir la liste des voitures issues d'une certaine usine, sachant qu'on a une liste d'usines ne fabriquant pas certaines marques de voitures...

Reply

Marsh Posté le 08-08-2004 à 11:10:02    

dapp a écrit :

je le dis comme ça mais c'est pas du copier/coller hein  :)  
 
Tamahome a bien compris le probleme, mais en mysql il n'y a pas de clés étrangères donc je ne vois pas comment on peut faire.


Si ce n'est pas du copier/coller, c'est toi qui doit apprendre à comprendre et reformuler un énoncer. Et tel qu'il est présenté là, ton énoncé ne laisse en rien imaginer qu'il faille utiliser la moindre FK pour exprimer la requète SQL dont tu pourrais avoir besoin.

Reply

Marsh Posté le 08-08-2004 à 11:10:02   

Reply

Marsh Posté le 08-08-2004 à 15:33:11    

- Une usine construit des voitures de marques différentes dans un pays donné
- cette usine ne construit pas une exception de marques
- l'usine ne construit que les voitures de son pays
>>> comment faire la liste des voitures d'une usine donnée------
 
J'ai donc posé mes tables comme suit:
- 1 table usine(nom,pays)
- 1 table voitures(marque,pays)
- 1 table exclusion(usine,marque)  
 
Point 1 et 3 - Le point 1 n'apporte aucune info en fait vu ton modèle - :
---------
SELECT voiture.nom
FROM voiture, usine
WHERE usine.nom = 'usine1'
and voiture.pays = usine.pays
 
Point 1 + 2 + 3 :
-------------
SELECT voiture.nom
FROM exculsion, voiture, usine
WHERE usine.nom = 'usine1'
AND voiture.pays = usine.pays
AND voiture.marque != exclusion.marque
AND usine.pays = usine.pays


Message édité par Arjuna le 08-08-2004 à 15:34:00
Reply

Marsh Posté le 08-08-2004 à 19:14:18    

c'est quoi l'intérêt de la dernière ligne:
 
AND usine.pays = usine.pays ?
elle est pas toujours vraie cette condition ?
 
 
point 1 et 3 donne en effet:
SELECT voitures.marque
FROM voitures, usine
WHERE usine.nom =  'A' AND voitures.pays = usine.pays
----
peugeot  
renault  
citroen  
----
 
Mais ta 2e requete ne donne rien qui vaille, elle n'a pas pris en compte le fait que l'usine A ne construit pas de renault et de peugeot et qu'on ne devrait avoir que citroen  :lol:


Message édité par dapp le 08-08-2004 à 19:21:14
Reply

Marsh Posté le 08-08-2004 à 19:21:39    

je pense qu'il faut faire des JOIN
si on fait une simulation, tu obtiens le résultat suivant:
 
usine.nom,exclusion.marque,voitures.marque,usine.pays:
A, renault, peugeot, fr
A, peugeot, renault, fr
...
C, golf, citroen, fr
 
-----
effectivement, à la lecture, on voit que l'usine A ne fabrique pas de Renault. Elle est en face d'une peugeot donc OK, on affiche.
Ligne 2: elle ne fabrique pas de peugeot, on est en face d'une renault donc OK, on affiche... mais n'a aucun souvenir de la ligne précédente.
 
 :D


Message édité par dapp le 08-08-2004 à 19:27:34
Reply

Marsh Posté le 08-08-2004 à 19:39:52    

dapp a écrit :

c'est quoi l'intérêt de la dernière ligne:
 
AND usine.pays = usine.pays ?
elle est pas toujours vraie cette condition ?
 
 
point 1 et 3 donne en effet:
SELECT voitures.marque
FROM voitures, usine
WHERE usine.nom =  'A' AND voitures.pays = usine.pays
----
peugeot  
renault  
citroen  
----
 
Mais ta 2e requete ne donne rien qui vaille, elle n'a pas pris en compte le fait que l'usine A ne construit pas de renault et de peugeot et qu'on ne devrait avoir que citroen  :lol:


Réfléchit deux secondes, je me suis planté dans ma dernière ligne tout simplement... C'est évidement usine.pays = voiture.pays :sarcastic:

Reply

Marsh Posté le 08-08-2004 à 19:51:24    

c'est pas pareil que le 1er AND ?
 
 
>>> SELECT voiture.marque
FROM exclusion, voitures, usine  
WHERE usine.nom = 'A'  
AND voitures.pays = usine.pays  
AND voitures.marque != exclusion.marque  
AND usine.pays = voitures.pays
 
simple question: as tu essayé ces requetes ?  :whistle:  parce que je suis déjà passé par celle là 36 fois et 42 variantes différentes mais nada, j'en ai une avec des inner join et des left join dans tous les sens mais toujours nada  :fou:  
 
 :lol:

Reply

Marsh Posté le 08-08-2004 à 19:54:31    

T'as rien de mieu à faire que de te foutre de ceux qui essaient de t'aider ?
 
Démerde-toi tout seul après tout.

Reply

Marsh Posté le 08-08-2004 à 20:03:28    

enfin... je ne me fous pas de toi, c'est que ça fait tellement de requetes que j'ai fait que plutot que de m'énerver, ça me prend tellement le chou que j'en ris...
 
après tout, vaut mieux en rire qu'en pleurer non ?
 
allons allons  [:andromaque] je ne voulais pas te vexer...
je disais donc: je pense qu'il faut mettre des JOIN (sans s, pas des joins  [:andromaque] )
 
qu'en penses tu ?


Message édité par dapp le 08-08-2004 à 20:03:51
Reply

Marsh Posté le 08-08-2004 à 20:08:51    

Ma requête conporte déjà des join, pas besoin de les expliciter quand c'est des inner join.
 
PS: ton truc, c'est obligatorement MySQL, ou si c'est toi qui te l'impose ? Parceque MySQL ne supportant pas les sous-requêtes (du moins dans la version standard) ta requête est quasi impossible.

Reply

Marsh Posté le 08-08-2004 à 20:15:34    

oui c'est un devoir en mysql
 
j'ai effectué maintes fois cette requete par exemple:
 
SELECT * FROM usine
LEFT JOIN exclusion ON exclusion.usine = usine.nom
 
ce qui donne ce résultat:
 

Code :
  1. nom  pays  usine  marque 
  2. A    FR    A      peugeot
  3. A    FR    A      renault
  4. B    FR    NULL   NULL
  5. C    DE    C      GOLF
  6. D    DE    NULL   NULL


 
 
puis WHERE usine.nom = 'A'
 

Code :
  1. nom  pays  usine  marque 
  2. A    FR    A      peugeot
  3. A    FR    A      renault


 
 :cry:

Reply

Marsh Posté le 08-08-2004 à 20:21:27    

Me demande pas comment j'ai fait, je comprends rien à la syntaxe que j'ai utilisé.
 
En tout cas ça marche (et testé)
5 minutes à tout casser... Faut faire un effort si t'y a vraiment passé la journeé :p
 
select *
from voitures left outer join exclusion on exclusion.marque = voitures.marque inner join usine on usine.pays = voitures.pays
where usine.nom = 'A'
and exclusion.usine is null

Reply

Marsh Posté le 08-08-2004 à 20:33:24    

je suis déjà passé par là  :pt1cable:  
 
dans ta requete, change A par B (on change d'usine)
et tu remarqueras que ça donne que citroen, alors que l'usine B (FR) n'a pas de liste d'exclusion donc on devrait retrouver
citroen,peugeot et renault  :)  
 
idem si tu essaies avec D
 
ta condition 'and exclusion.usine is null' est trop restrictive...

Reply

Marsh Posté le 08-08-2004 à 20:48:29    

spa compliqué pourtant, suffit de comprendre ma syntaxe merdique et la corriger :p
 
SELECT  voitures.marque
FROM voitures inner join usine on voitures.pays = usine.pays
LEFT  OUTER  JOIN exclusion ON exclusion.marque = voitures.marque and exclusion.usine = usine.nom
WHERE usine.nom =  'D'  
and exclusion.usine is null


Message édité par Arjuna le 08-08-2004 à 20:51:03
Reply

Marsh Posté le 08-08-2004 à 20:48:44    

ce coup-ci ça marche pour les 4 usines

Reply

Marsh Posté le 08-08-2004 à 21:04:03    

ma foi ça a l'air de marcher  :jap:  ...
 
tu sais quoi ? j'ai commencé à dérailler  :lol:  j'ai contourné le problème:
 
ma liste d'exclusion ressemble à ça maintenant:
A,peugeot-renault
C,golf
 
 
autrement dit j'ai tout concaténé et au lieu de faire des jointures, je fais des 'locate'  :sarcastic:  
 
c'est quoi la différence entre left join et left outer join ?

Reply

Marsh Posté le 08-08-2004 à 21:07:11    

LEFT JOIN logiquement est égale à un RIGHT JOIN, tous deus égaux à un INNER JOIN. En fait, le INNER JOIN est, d'après mes souvenirs, le raccourci uitliser pour RIGHT INNER JOIN et LEFT INNER JOIN. En effet, lors d'un INNER join, que ce soit une jointure droite ou gauche, vu qu'elle est exclusive, le comportement est rigoureusement le même. Hors INNER est le type de jointure par défaut.
 
Par contre, le OUTER join étant inclusif, il faut impérativement spécifier LEFT ou RIGHT. Je ne sais pas si l'un des deux est par défaut.

Reply

Marsh Posté le 08-08-2004 à 21:17:27    

:jap:  ... je vais agrandir ma liste de voitures et j'essaie de décortiquer un peu mieux ta requete...
 
je pense qu'il me fallait une vision nouvelle de la chose
merci du tuyaux

Reply

Marsh Posté le 08-08-2004 à 23:04:05    

Arjuna a écrit :

LEFT JOIN logiquement est égale à un RIGHT JOIN, tous deus égaux à un INNER JOIN. En fait, le INNER JOIN est, d'après mes souvenirs, le raccourci uitliser pour RIGHT INNER JOIN et LEFT INNER JOIN. En effet, lors d'un INNER join, que ce soit une jointure droite ou gauche, vu qu'elle est exclusive, le comportement est rigoureusement le même. Hors INNER est le type de jointure par défaut.
 
Par contre, le OUTER join étant inclusif, il faut impérativement spécifier LEFT ou RIGHT. Je ne sais pas si l'un des deux est par défaut.


Perdu. LEFT INNER JOIN et RIGHT INNER JOIN n'existent pas car ils n'ont aucun sens. Quand on spécifie un LEFT ou un RIGHT, il s'agit obligatoirement d'une jointure externe.

Reply

Marsh Posté le 08-08-2004 à 23:25:56    

Je vois pas en quoi j'ai "perdu".
Le INNER JOIN se passe de LEFT et RIGHT pour la raison que j'ai énnoncé. Rien n'empêche un SGBD de les accepter, car autant ils sont inutiles, autant ils n'interfèrent en rien le fonctionnement de la requête s'ils sont pris en charge. De mémoire, avec Ingre (bas avec laquelle je bossais lors de mes études), LEFT et RIGHT étaient supportés par le INNER JOIN.

Reply

Marsh Posté le 09-08-2004 à 08:51:59    

Perdu dans le sens où LEFT/RIGHT INNER JOIN n'existent pas dans le standard SQL. ;)

Reply

Marsh Posté le 09-08-2004 à 08:56:20    

Vi, mais pas dans la raison de leur non-existence :p ;)

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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