intersection d'ensembles? - SQL/NoSQL - Programmation
Marsh Posté le 20-10-2014 à 22:22:35
Salut !
dans ta question 7 :
Qui a reçu tous les cadeaux qu'il avait souhaité ?
tu as deux tables, où tu as les informations correspondantes :
SOUHAIT (n°personne, âge_anniversaire, cadeau)
OFFERT (n°personne offrant, n°personne recevant, âge_anniversaire, cadeau)
select a.n°personne ,count(distinct a.cadeau)), count(distinct (b.cadeau))
from souhait as a inner join offetr as b
on a.n°personne = b.n°personne recevant
and a.cadeau = b.cadeau
(and a.age_anniversaire = b.age_anniversaire à voir, c'est pas dit dans l'énoncé))
where count(distinct a.cadeau)) = count(distinct (b.cadeau))
group by a.n°personne (ajouté a.age_anniversaire)
A voir pour la syntaxe, car elle est faite comme ça sans avoir de sql sous la main
Guillaume
Marsh Posté le 21-10-2014 à 09:13:56
Merci d'y avoir passé un peu de temps!
Non, ça ne marche pas. Au cas où, je suis sous mysql.
Le problème vient que :
Code :
|
il n'en veut pas.
Si je remplace par
Code :
|
ça passe, mais c'est faux puisque cette condition est toujours vraie puisque c'est une condition de la jointure (si je ne dis pas de betise)
Donc je me retrouve avec tous la liste de toutes les personnes
Marsh Posté le 21-10-2014 à 10:27:51
Merci, je crois que j'ai un truc qui a l'air de fonctionner
Code :
|
Marsh Posté le 21-10-2014 à 10:57:20
Pour rappel, les fonctions d’agrégation (comme count, max, sum...) ne se mettent pas dans le WHERE mais dans le SELECT. Dans le HAVING, c'est possible aussi mais tu peux t'en passer en mettant des alias aux count() du select et en utilisant ces alias dans le having
Marsh Posté le 21-10-2014 à 13:13:26
C'était pour expliquer pourquoi le count() (qui est une fonction d'agrégation) placé dans la clause WHERE ne fonctionnait pas
Pour le having, je voulais juste dire qu'on pouvait utiliser les alias comme ceci :
SELECT nom, count(a.cadeau) as NB_Cadeaux1, count(b.cadeau) as NB_Cadeaux2 FROM ... WHERE... GROUP BY nom HAVING NB_Cadeaux1 = NB_Cadeaux2
Marsh Posté le 21-10-2014 à 15:16:12
Salut
Sinon antiseptiqueindolore, l'exo est egalement "faisable" en utilisant des counts() comme tu essayais de le faire initialement, il faut juste jouer un peu avec la structure de la requete et c'est pas vraiment intuitif .
Celle-ci devrait marcher:
SELECT p.nom, p.prenom |
Cependant attention: ca ne marche que si les cadeaux offerts sont forcement pris parmi les cadeaux souhaites. L'exercice ne precise pas. Mais si par exemple Robert veut un chou et que Roger lui offre une carotte, la requete au-dessus ne marche plus et doit etre "amelioree":
SELECT p.nom, p.prenom |
Au final ca reste un peu plus complique que ta propre solution, mais ca reste possible.
Pour finir, tu peux essayer un truc comme ca mais de tete je doute que ca marche (j'ai rien de lance pour verifier la maintenant):
SELECT p.nopersonne, p.nom, p.prenom |
L'idee est "claire" mais de tete je me souviens pas si en SQL on peut utiliser des fonctions non-agregees dans la clause HAVING. (Edit: et puis si le moteur etend le "scope" de p.nopersonne jusque dans la sous-requete)
Re-edit: j'me rends aussi compte que ta requete tout comme les miennes ne marcheront que si une personne ne souhaite un meme cadeau qu'une seule fois et n'est offert ce cadeau qu'une seule fois.
Sinon:
- Ta requete ne marche plus parce que Robert demandant une tomate 10 ans de suite serait "couvert" par Roger lui offrant une tomate une seule fois
- La mienne ne marche plus parce que les JOINs ne font plus du "1 pour 1" et du coup ca va fausser les comptes
Bref encore un exo "mal pense"
Marsh Posté le 21-10-2014 à 15:51:24
Je regarde un peu ta solution 2.
Le truc aussi c'est qu'on peut demander 2 cadeaux et en recevoir 3.
Ton JOIN c'est un INNER JOIN?
Marsh Posté le 21-10-2014 à 16:08:52
Mh oui je sais plus, le JOIN de base, celui qui degage la personne du resultat si elle a pas de souhaits. Oui ca doit etre INNER.
Marsh Posté le 21-10-2014 à 16:42:26
JOIN, dans la norme SQL, il me semble que c'est le produit cartésien, donc le CROSS JOIN dans Mysql. Le INNER JOIN, c'est l'équi-jointure.
Marsh Posté le 21-10-2014 à 16:42:45
je capitule ça compile pas, et j'ai pas encore les billes pour arriver à jongler avec la syntaxe comme ça
Marsh Posté le 21-10-2014 à 17:10:08
Roh
Du coup j'ai lance Oracle pour checker, il y a effectivement deux erreurs dans la seconde requete:
- la table PERSONNE ne prend pas de s a la fin
- la clause WHERE c'est plutot WHERE rcs.nb_recus = shs.nb_offerts
Sinon ca marche.
Mon test:
- Robert veut un pacemaker pour ses 75 ans, Roger un dentier pour ses 77.
- Robert offre le dentier, youpi!
- Roger lui est un gros radin et offre une canne a la place du pacemaker
create table PERSONNE ("n°personne" number, "nom" varchar2(50), "prénom" varchar2(50), "date_naissance" date); |
Ca retourne bien que Roger est content (en plus d'etre radin, elle est pas belle sa vie?)
Edit: jai teste aussi la derniere requete avec le HAVING COUNT, ben elle marche aussi, comme quoi. (sous Oracle en tout cas)
SELECT p."n°personne", p."nom", p."prénom" |
Marsh Posté le 21-10-2014 à 18:13:14
ok ta requete elle s'execute avec mysql si je mets SYSDATE() et que je respecte la casse, mais là ça doit etre un pb linux
Marsh Posté le 21-10-2014 à 18:31:13
Ah oui effectivement mon test est sous Oracle donc il va peut-etre y avoir quelques differences de syntaxe avec MySql. Par contre je peux pas t'aider avec ca mais ca devrait pas etre insurmontable.
Marsh Posté le 21-10-2014 à 20:16:31
rufo a écrit : JOIN, dans la norme SQL, il me semble que c'est le produit cartésien, donc le CROSS JOIN dans Mysql. Le INNER JOIN, c'est l'équi-jointure. |
"En l'absence d'un type de jointure explicite, la jointure sera considérée comme interne (INNER JOIN)"
Souhaitez moi bonne chance pour demain, je suis un expert en bases de données
Marsh Posté le 21-10-2014 à 20:17:26
il doit y avoir un truc ! dans l'énoncé ou alors le mec c'est gourré
car au vue des questions précédentes lol
les solutions proposées sur carrément d'un autre niveau
le having de rufo, ne suffit pas?
Marsh Posté le 21-10-2014 à 20:28:33
rufo tu as une solution?
Je contacte l'auteur du sujet aussi, pour savoir ce qu'elle a pensé
Marsh Posté le 21-10-2014 à 20:45:51
Non mais vu le reste des questions, la reponse c'est a mon avis aucune des solutions proposees ici.
Le NOT IN propose au debut par antiseptique fait l'affaire en gros mais vu l'imprecision du sujet je suppute fortement qu'ils attendent qu'on fasse la jointure sur age + cadeau plutot que sur seulement cadeau.
Et c'est tout.
Les trucs que j'ai ajoute pour montrer comment on peut faire avec count() et having c'etait juste pour montrer que c'est possible mais je doute fortement que ca soit la reponse attendue.
Marsh Posté le 23-10-2014 à 12:35:18
antiseptiqueincolore : mets la correction, stp
Marsh Posté le 23-10-2014 à 12:38:06
l'auteur du sujet n'a pas répondu à mon mail, donc je n'en sais pas plus
Marsh Posté le 24-10-2014 à 08:55:52
Moi j'aurais fait ca:
Code :
|
Si il faut le nom, prenom il suffit de faire a join avec Personne.
Marsh Posté le 20-10-2014 à 19:47:45
Bonjour,
alors je sais qu'on ne répond pas aux demandes de résolutions d'exos, mais ça n'est pas mon exo, et je ne dois le rendre à personne
mais si ça ne va pas, on ferme et puis c'est tout.
Le pdf d'exos est ici
http://cedric.cnam.fr/~crucianm/src/ED-SQL.pdf
c'est l'exo 3, la question 7. Je sèche
Qui a reçu tous les cadeaux qu'il avait souhaité?
Je vois bien que pour chaque personne, l'ensemble des cadeaux reçus doit contenir l'ensemble des cadeaux demandés, mais je ne vois pas comment l'écrire
Si vous avez une idée, ça me permettra de comprendre, merci