Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2936 connectés 

 


 Mot :   Pseudo :  
 
 Page :   1  2  3  4  5
Auteur Sujet :

Projet SQL

n°1559823
MagicBuzz
Posté le 14-05-2007 à 09:17:07  profilanswer
 

Reprise du message précédent :
oublie les exists et autres.
 
le prof a parlé de jointure externe, et c'est faisable avec une jointure externe.
 
=> tous ceux qui n'ont pas fait d'examen
 
Ca se traduit de 3 manières différentes :
- Tous les patients SAUF (not exists / not in) ceux qui ont passé un exament (nécessite une sous-requête)
- Tous les patients MOINS ceux qui ont passé un exeman (DIFFERENCE) (supporté sur PostGreSQL, et pas grand chose d'autre)
- Le CONTRAIRE de ceux qui ont passé un exament (OUTER JOIN) (supporté par tous les SGBD dans toutes leurs versions - ou presque -)
 
Pour trouver la syntaxe avec le "contraire", commence par faire ta requête normalement avec des INNER JOIN tout ce qu'il y a de plus classique, affin de trouver ceux qui ont passé un exament.
Ensuite, modifie ton INNER JOIN en LEFT/RIGHT OUTER JOIN, et compare les résultats : dans les champs de "examen", pour les clients qui n'en ont jamais passé, tu as la valeur "null".
=> T'as plus qu'à rajouter un test sur un de ces champs déclaré en "NOT NULL" dans la table histoire de ne pas te faire avoir par des données incomplètes, afin d'isoler tout ceux qui n'ont jamais passé d'exament.


Message édité par MagicBuzz le 14-05-2007 à 09:20:49
mood
Publicité
Posté le 14-05-2007 à 09:17:07  profilanswer
 

n°1559830
gocho
Posté le 14-05-2007 à 09:33:33  profilanswer
 

la difference, c'est bien le MINUS?
il est supporté sur Oracle aussi.
 
 
Sinon, pour le outer join, j'ai jamais aimé m'en servir :o  (...enfin on me l'a pas appris au début, donc j'ai toujours fait sans :p)
 
Ca apporte quoi, mis a part une compatibilité plus étendue?

n°1559832
MagicBuzz
Posté le 14-05-2007 à 09:37:18  profilanswer
 

Ah oui, c'est MINUS, tu as raison :jap:
 
Un peu plus rapide (ça peut être beaucoup plus rapide sur de très grosses requêtes)
Mais perso j'aime pas des masses, car on perd énormément en lisibilité.

n°1559835
MagicBuzz
Posté le 14-05-2007 à 09:41:41  profilanswer
 

Sinon, moi quand on me l'a appris, j'ai bloqué (mal expliqué peut-être) et du coup ce n'est que "récemment" que j'ai enfin pigé comment ça marche. En fait c'est tout couillon :)
 
J'ai des clients (table "client" ) et des commandes (table "commande" )
 
FK entre commande.client_id et client.id
 
Liste de tous les clients ayant passés une commande, ainsi que les numéros de commande :
 
select client.id, commande.id
from client inner join commande on client.id = commande.client_id
 
=> Jusque là, tu suis ? :D
 
Même chose, mais que les clients aient passé commande ou non :
 
select client.id, commande.id
from client left outer join commande on client.id = commande.client_id
 
=> Là, j'ai des <null> dans la colonne "commande.id"
Ces NULL ont été insérés pour chaque client qui n'a pas de commande.
Donc pour avoir la liste des clients qui n'ont jamais passé de commande, il suffit de ne garder que ceux qui sont à NULL.
 
select client.id, commande.id
from client left outer join commande on client.id = commande.client_id
where commande.id is null
 
=> Et voilà !

n°1559836
MagicBuzz
Posté le 14-05-2007 à 09:42:08  profilanswer
 

ps : entre left et right, je sais jamais lequel est bon :ange: faut tester jusqu'à ce que ça marche [:cerveau boulay]


Message édité par MagicBuzz le 14-05-2007 à 09:42:30
n°1559838
lumi
Posté le 14-05-2007 à 09:44:20  profilanswer
 

moi j'ai mis ca:

 

select distinct cl.nom_client from client as cl
where not exists (
select e.code_examen
from examen as e, ordonnance as o
where e.code_examen=o.code_examen
and e.code_client=cl.code_client
and e.type_examen='radiographie';

 


pour l'instant ca fonctionne pas


Message édité par lumi le 14-05-2007 à 09:45:23

---------------

n°1559840
MagicBuzz
Posté le 14-05-2007 à 09:49:07  profilanswer
 

1/ normal, t'as pas fermé la parenthèse (pas lu le reste)
2/ ton prof a demandé une jointure externe :p (tu peux coller la solution avec exists et minus en plus si tu veux, mais préfère donner la réponse attendue, car y'a des profs très cons... entre maintenabilité et rapidité ils font pas forcément la différence, puisqu'ils n'ont jamais été confrontés à la vraie vie. perso, je préfère le lisible car je fais de la TMA. d'autres préfèreront la rapidité. mais y'a surtout des intégristes dans les deux bords, donc dans tous les cas, fait ce qu'on te demande, et après seulement, propose d'autres solutions ;)

n°1559842
lumi
Posté le 14-05-2007 à 09:50:14  profilanswer
 

cette requete fonctionne, a verrifier qu'elle me donne le resultat attendu

 

select distinct cl.nom_client from client as cl, examen as e, ordonnance as o where e.code_examen=o.code_examen and o.code_client=cl.code_client and e.type_examen not in ('radiographie');

 


celle la aussi apres correction de la parenthese et d'une erreure sur e.code_client <==> o.code_client

 

select distinct cl.nom_client from client as cl where not exists ( select e.code_examen from examen as e, ordonnance as o where e.code_examen=o.code_examen and o.code_client=cl.code_client and e.type_examen='radiographie');

 


edit : sauf que ca ne donne pas le meme resultat :D

Message cité 1 fois
Message édité par lumi le 14-05-2007 à 09:52:42

---------------

n°1559844
lumi
Posté le 14-05-2007 à 09:51:01  profilanswer
 

MagicBuzz a écrit :

1/ normal, t'as pas fermé la parenthèse (pas lu le reste)
2/ ton prof a demandé une jointure externe :p (tu peux coller la solution avec exists et minus en plus si tu veux, mais préfère donner la réponse attendue, car y'a des profs très cons... entre maintenabilité et rapidité ils font pas forcément la différence, puisqu'ils n'ont jamais été confrontés à la vraie vie. perso, je préfère le lisible car je fais de la TMA. d'autres préfèreront la rapidité. mais y'a surtout des intégristes dans les deux bords, donc dans tous les cas, fait ce qu'on te demande, et après seulement, propose d'autres solutions ;)


 
 
apres avoir demandé au prof, c'etais juste un conseil la jointure externe, aucunne obligation d 'utilisation


---------------

n°1559849
lumi
Posté le 14-05-2007 à 09:54:33  profilanswer
 

celle ci semble etre la bonne :
 
select distinct cl.nom_client from client as cl where not exists ( select e.code_examen from examen as e, ordonnance as o where e.code_examen=o.code_examen and o.code_client=cl.code_client and e.type_examen='radiographie');


---------------

mood
Publicité
Posté le 14-05-2007 à 09:54:33  profilanswer
 

n°1559851
MagicBuzz
Posté le 14-05-2007 à 10:01:34  profilanswer
 

lumi a écrit :

cette requete fonctionne, a verrifier qu'elle me donne le resultat attendu  
 
select distinct cl.nom_client from client as cl, examen as e, ordonnance as o where e.code_examen=o.code_examen and o.code_client=cl.code_client and e.type_examen not in ('radiographie');
 
 
celle la aussi apres correction de la parenthese et d'une erreure sur e.code_client <==> o.code_client
 
select distinct cl.nom_client from client as cl where not exists ( select e.code_examen from examen as e, ordonnance as o where e.code_examen=o.code_examen and o.code_client=cl.code_client and e.type_examen='radiographie');
 
 
edit : sauf que ca ne donne pas le meme resultat :D


la première n'est pas bonne, car elle donne la liste de tous les patients qui ont passé au moins un examen, mais jamais de radios : du coup les patiens qui n'ont jamais passé d'examen ne sont pas trouvés

n°1559856
lumi
Posté le 14-05-2007 à 10:07:03  profilanswer
 

MagicBuzz a écrit :

la première n'est pas bonne, car elle donne la liste de tous les patients qui ont passé au moins un examen, mais jamais de radios : du coup les patiens qui n'ont jamais passé d'examen ne sont pas trouvés


 
 
ok merci pour l'explications, je ne comprenais pas pourquoi
 


---------------

n°1559858
lumi
Posté le 14-05-2007 à 10:09:26  profilanswer
 

pour la suivante, petit souci
 
on nous demande d'afficher tous les examen et les date de commande
 
 
sauf qu'une bon nombre d'examens que j'ai créé dans la table existent "dans la theorie" mais n'ont jamais été commandé
 
je ne sais pas quoi afficher
je donne ca :
 
 
select distinct e.nom_examen, e.type_examen, o.date_ordonnance from examen as e, ordonnance as o where e.code_examen=o.code_examen ;
 
 
mais la il affiche tous les examen qui ont été commandé au moins une fois
 
apres j'aurai pu simplement créer les examens qui ont été commandé et laisser tous les autres de coté  [:spamafote]


---------------

n°1559862
MagicBuzz
Posté le 14-05-2007 à 10:15:30  profilanswer
 

après, ça dépend s'il les veut tous (y compris les pas commandés ou non)
 
s'il les veut tous, il faut justement utiliser une jointure ouverte. et tu auras "null" dans la date pour ceux qui n'ont jamais été commandés.
 
par contre, ceux qui ont été commandés plusieur fois, tu fais comment ?

n°1559863
lumi
Posté le 14-05-2007 à 10:18:05  profilanswer
 

MagicBuzz a écrit :

après, ça dépend s'il les veut tous (y compris les pas commandés ou non)
 
s'il les veut tous, il faut justement utiliser une jointure ouverte. et tu auras "null" dans la date pour ceux qui n'ont jamais été commandés.
 
par contre, ceux qui ont été commandés plusieur fois, tu fais comment ?


 
 
j'ai créé 30 examens possibles, mais seulement 11 commande d'examen...donc aucun ne revient 2 fois


---------------

n°1559864
lumi
Posté le 14-05-2007 à 10:19:02  profilanswer
 

affichez les clients qui ont passé un examen radiologique et les services qui realisent un tel examen....


---------------

n°1559866
lumi
Posté le 14-05-2007 à 10:19:31  profilanswer
 

et il conseil un UNION de deux jointures complexes


---------------

n°1559883
lumi
Posté le 14-05-2007 à 10:46:33  profilanswer
 

probleme : apres avoir essayer d'utiliser le "union"
 
le ; n'arrete plus la requete  
 
 
et au lieu d'avoir ca -> devant mes ligne j'ai ca ">
 
:heink:


---------------

n°1559884
MagicBuzz
Posté le 14-05-2007 à 10:48:30  profilanswer
 

hein ?
 
sinon, le union, t'en a besoin pour quoi là ?
parceque je ne vois pas du tout à quoi il peut te service dans ton cas

n°1559886
lumi
Posté le 14-05-2007 à 10:52:08  profilanswer
 

ben sans union je vais pouvoir afficher les client qui ont passé un examen radiologique ainsi que le service dans le quel on peut le passer
mais pas
 
tous les service qui propose ce type d examen


---------------

n°1559887
MagicBuzz
Posté le 14-05-2007 à 10:52:39  profilanswer
 

lumi a écrit :

affichez les clients qui ont passé un examen radiologique et les services qui realisent un tel examen....


cette question est débile.
 
si j'ai bien pigé, c'est pour y répondre qu'il préconnise un UNION ?
 
moi je préconnise de ne surtout pas y répondre ! du moins pas avec un UNION (t'as qu'à lui mettre mon post en copie et qu'il vienne s'il est pas content :o)
 
c'est deux requêtes différentes, faut pas mélanger les petits-poids et les carrotes même si c'est bon avec des petits lardons.
 
=> requête correcte (en une fois) : pour chaque client qui a passé un examen de radiologie, afficher la liste des centres qui proposent cet exament : débile comme façon de faire, il va y avoir des millions de doublons)
=> pour chaque centre d'examen proposant la radiologie, afficher la liste des patiens qui ont effectivement passé un examen de radiologie dedans (déjà mieux comme solution, moins de doublons)
=> liste des clients qui ont passé une radio + liste des centres d'exam qui proposent la radiologie (2 requêtes) <- mais en aucun cas faut les mettre en UNION. c'est débile, programmatiquement parlant ce sera inutilisable, ça n'a rigoureusement aucun intérêt.


Message édité par MagicBuzz le 14-05-2007 à 10:53:19
n°1559895
lumi
Posté le 14-05-2007 à 10:59:01  profilanswer
 

bne justmeent, avec la requete que je test, ca me met les noms de client et les noms de service dans la meme colonne sous : nom_client

 


select cl.nom_client
    -> from client as cl, examen as e, ordonnance as o
    -> where cl.code_client=o.code_client
    -> and e.code_examen=o.code_examen
    -> and e.type_examen='radiographie'
    -> union
    -> select distinct s.nom_service
    -> from service as s, examen as e
    -> where s.code_service=e.code_service
    -> and e.type_examen='radiographie'
    -> ;


Message édité par lumi le 14-05-2007 à 10:59:19

---------------

n°1559908
lumi
Posté le 14-05-2007 à 11:11:57  profilanswer
 

select distinct e.type_examen, e.nom_examen, max(o.date_ordonnance) from examen as e, ordonnance as o where e.code_examen=o.code_examen;
ERROR 1140 (42000): Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause
 
 


---------------

n°1559915
joce
Architecte / Développeur principal
&#034;BugHunter&#034;
Posté le 14-05-2007 à 11:15:59  profilanswer
 

si tu mets pas de group by aucune chance que le max() fonctionne


Message édité par joce le 14-05-2007 à 11:16:08

---------------
Protèges carnets personnalisés & accessoires pour bébé
n°1559917
MagicBuzz
Posté le 14-05-2007 à 11:16:49  profilanswer
 

oui, et comme je dis, c'est mal.
 
essaie d'ajouter un "order by 1" pour trier les noms par ordre alphabétique, tu vas voir ce que ça va donner...
 
depluis, à la relecture, comment programmatiquement tu différencies les deux ?
de plus, le nom des champs est différent, donc pour récupérer la chose programmatiquement parlant, c'est la plaie.
 
ps : "union all" au lieu de "union" car plus rapide et permet d'afficher le client "dupont" et le centre "dupont"
 
solution batarde, à la limite :
 
select distinct 'client' tbl, cl.nom_client nom    -- distinct ici, car un client peut passer deux radios
from client as cl, examen as e, ordonnance as o
where cl.code_client=o.code_client
and e.code_examen=o.code_examen
and e.type_examen='radiographie'
union all
select 'service' tbl, s.nom_service nom  -- pas de distinct car un centre ne peux normalement pas proposer deux fois le même examen, si ?
from service as s, examen as e
where s.code_service = e.code_service
and e.type_examen = 'radiographie'

n°1559923
MagicBuzz
Posté le 14-05-2007 à 11:19:06  profilanswer
 

=> l'ajout du champ "tbl" permet de différencier les clients des services. mais très franchement, je trouve ça très sale pas et forcément exploitable programmatiquement parlant. il faut toujours garder à l'esprit que le SQL est généralement appelé par un programme, et souvent les requêtes sont plus ou moins construites automatiquement. donc les trucs "pas propres" de la sorte, c'est le mal

n°1559927
lumi
Posté le 14-05-2007 à 11:22:40  profilanswer
 

affichez les clients qui ont commandé une biopsie
 
select distinct cl.nom_client from client as cl, ordonnance as o, examen as e where cl.code_client=o.code_client and e.code_examen=o.code_examen and e.nom_examen='biopsie';
 
select distinct cl.nom_client from client as cl, ordonnance as o, examen as e where cl.code_client=o.code_client and e.code_examen=o.code_examen and e.nom_examen in ('biopsie');
 
 
les deux fonctionne, mais il nous conseil le in
 
 
sont-elles correctes ?


---------------

n°1559930
MagicBuzz
Posté le 14-05-2007 à 11:25:56  profilanswer
 

je pige pas pkoi il préconise un "in"
en tout cas, certainement pas de la façon dont il est utilisé dans la seconde requête.
 
la première requête me semble parfaite :spamafote:

n°1559939
lumi
Posté le 14-05-2007 à 11:31:12  profilanswer
 

MagicBuzz a écrit :

je pige pas pkoi il préconise un "in"
en tout cas, certainement pas de la façon dont il est utilisé dans la seconde requête.

 

la première requête me semble parfaite :spamafote:

 


on a une seconde requete ou il faut trouver les client qui ont fait un examen radiologique mais jms de biopsie


Message édité par lumi le 14-05-2007 à 11:31:24

---------------

n°1559942
lumi
Posté le 14-05-2007 à 11:31:43  profilanswer
 

d apres ce que moi j'ai capté, ici le in peut s utiliser exactement comme le =


---------------

n°1559964
MagicBuzz
Posté le 14-05-2007 à 11:41:36  profilanswer
 

Le IN est un "=" qui est exécuté sur une liste de valeurs (avec un OR entre chaque test).
La liste peut être une série de constantes séparées par des virgules, ou les lignes d'une sous-requête (un seul champ retourné par la sous-requête !)
 
Pour ce qui est de ta requête, effectivement, un NOT IN est pas mal :
=> Tous ceux qui ont fait une radio "not in" tous ceux qui ont fait de la biopsie)
 
select client.nom
from mes tables
where j'ai fait de la radio
and client.id not in (select client.id fomr mes tables where j'ai fait de la biopsie)

Message cité 1 fois
Message édité par MagicBuzz le 14-05-2007 à 11:42:56
n°1559968
lumi
Posté le 14-05-2007 à 11:44:14  profilanswer
 

select distinct cl.nom_client from client as cl, ordonnance as o, examen as e where cl.code_client=o.code_client and e.code_examen=o.code_examen and e.type_examen ='radiographie' and not exists (select cl.nom_client where e.code_examen=o.code_examen and cl.code_client=o.code_client and e.nom_examen in('biopsie'));


---------------

n°1559970
lumi
Posté le 14-05-2007 à 11:44:59  profilanswer
 

MagicBuzz a écrit :

Le IN est un "=" qui est exécuté sur une liste de valeurs (avec un OR entre chaque test).
La liste peut être une série de constantes séparées par des virgules, ou les lignes d'une sous-requête (un seul champ retourné par la sous-requête !)
 
Pour ce qui est de ta requête, effectivement, un NOT IN est pas mal :
=> Tous ceux qui ont fait une radio "not in" tous ceux qui ont fait de la biopsie)
 
select client.nom
from mes tables
where j'ai fait de la radio
and client.id not in (select client.id fomr mes tables where j'ai fait de la biopsie)


 
 
pour le prof faudrait garder le in de la requete precdente et faire un not exists en plus


---------------

n°1559972
MagicBuzz
Posté le 14-05-2007 à 11:46:23  profilanswer
 

ben non, le in, s'il ne porte que sur une valeur, ne sert absolument à rien.
 
amène le ici que je lui casse les dents :o

n°1559974
lumi
Posté le 14-05-2007 à 11:47:32  profilanswer
 

MagicBuzz a écrit :

ben non, le in, s'il ne porte que sur une valeur, ne sert absolument à rien.
 
amène le ici que je lui casse les dents :o


 
 
:D j le reverai plus  
 
 
sinon tu peux me dire l'erreur de ma requete juste audessus, je capte pas


---------------

n°1559975
MagicBuzz
Posté le 14-05-2007 à 11:48:03  profilanswer
 

je crois piger...
 
tu veux dire que...
 
=> il faut "la liste des client where exists ceux qui ont fait une radion and not in ceux qui ont fait de la biopsie" ?????? il est fou ton prof :o

n°1559977
MagicBuzz
Posté le 14-05-2007 à 11:48:43  profilanswer
 

y'a pas de from dans ta sous-requête

n°1559981
lumi
Posté le 14-05-2007 à 11:51:33  profilanswer
 

MagicBuzz a écrit :

y'a pas de from dans ta sous-requête


 
 
ok, il faut que je remette from les trosi tables que j'ai utilisé en haut ?


---------------

n°1559985
lumi
Posté le 14-05-2007 à 11:54:16  profilanswer
 

c'est cool elle fonctionne avec les from


---------------

n°1559986
lumi
Posté le 14-05-2007 à 11:54:51  profilanswer
 

le prix moyen d'un examen radiologique

 

la fonctionne avg ?

 


select  avg(prix_examen) from examen where type_examen='radiographie';
+------------------+
| avg(prix_examen) |
+------------------+
|         119.5455 |

 


c'est correcte ?


Message édité par lumi le 14-05-2007 à 12:00:01

---------------

n°1560001
MagicBuzz
Posté le 14-05-2007 à 12:10:15  profilanswer
 

oui, avg s'utilise comme ça.
par contre ça marche comme le MIN/MAX/COUNT/SUM : faut mettre des group by si tu retournes d'autres champs

mood
Publicité
Posté le   profilanswer
 

 Page :   1  2  3  4  5

Aller à :
Ajouter une réponse
 

Sujets relatifs
import gros fichier SQL dans MysqlProb : Type de données VB6 et SQL Server
cherche codeur pour projet 3dCorrection d'une requete SQL Delete....
Projet SGBD / Access / SQL => Compatibilité logiciels[SQL/NOOB] cherche de l'aide sur un projet de base de données
Lister toutes les requettes SQL du projet en PHP ?PROJET BASE DE DONNEE ACCESS SQL GRAPHIQUE ? HELP PLEASE
SQL Projet de base de données bibliotheque[SQL] HELLO, Gros projet-->Générateur de requêtes sql
Plus de sujets relatifs à : Projet SQL


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)