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

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  jointure dans le where ou dans le from

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

jointure dans le where ou dans le from

n°1607161
dodo
Posté le 01-09-2007 à 22:22:53  profilanswer
 

Bonjour,
 
je me pose une question toute simple chaque fois que je dois faire une jointure. laquelle choisir ?  
Est-ce qu'il vaut mieux privilégier une jointure dans le from via inner join ON, join on, left join On ou alors une jointure dans le where

mood
Publicité
Posté le 01-09-2007 à 22:22:53  profilanswer
 

n°1607449
MagicBuzz
Posté le 03-09-2007 à 10:04:37  profilanswer
 

question d'habitude et de préférence.
 
perso, j'ai longtemps préféré les jointures dans le where, car je les trouvais plus lisible.
 
jusqu'au jour où je me suis heurté à des cas à la con, impossibles à écrires avec ce système. maintenant je préfère avec les join.
 
dans tous les cas, il m'arrive de mélanger les deux, genre faire un "inner join" sur une sous-requête, je trouve ça passablement illisible, donc je faire mon join dans le where.
 
habitue toi aux deux syntaxe, et préfère celle du from afin de ne pas être bloqué je jour où tu devras faire des full outer join et des left/right outer join en cascade.
 
cependant, n'oublie pas l'autre pour autant, certains sgbd ont du mal avec les jointures dans le from (oracle jusqu'à la 9i par exemple si je ne m'abuse)


Message édité par MagicBuzz le 03-09-2007 à 10:05:22
n°1607466
anapajari
s/travail/glanding on hfr/gs;
Posté le 03-09-2007 à 10:27:52  profilanswer
 

JOINS FTW!!!
 
Plus sérieusement je suis d'accord avec Magic, c'est une question d'habitude.
Perso je peux pas supporter les clauses de jointure dans les wheres. Je trouve ça illisible et dangereux ( c'est le meilleur moyen de transformer un outer en inner sans s'en apercevoir).
Mais bon les goûts et les couleurs :o

n°1607562
dodo
Posté le 03-09-2007 à 12:28:07  profilanswer
 

merci pour  ces précisions,
 
donc cela ce vaut si j'ai bien compris juste une question d'habitude.
 
par contre c'est quoi ? full outer  

n°1607599
MagicBuzz
Posté le 03-09-2007 à 14:17:25  profilanswer
 
n°1607738
dodo
Posté le 03-09-2007 à 20:03:47  profilanswer
 

merci de ce lien très utile, je vais jeter un oeil car apparement je pensait que toutes les jointures donnait le même résultat, mais apparament c'est pas le cas.
 
j'ai une deuxième question dans le cas d'utilisation  de fonction dans le select comme avg, sum, count etc.
 
est ce que dans le cas d'une comparaison d'un element utilisant une fonction on peux le faire dans le where ou doit-on passer par une clausz group by et having
 

n°1607824
MagicBuzz
Posté le 04-09-2007 à 08:10:24  profilanswer
 

ça dépend des fonctions.
 
les fonctions d'agrégat telles que avg, sum ou count nécessivent effectivement d'utiliser having et group by. on ne peut pas les trouver dans une clause where.
 
mais des fonctions de valeur telles que les fonctions de cast, formattage de chaîne, etc. s'utilisent comme n'importe quel champ.
 

Code :
  1. SELECT avg(note) moyenne, nom
  2. FROM devrois
  3. WHERE to_char(date, 'YYYY') = '2007'
  4. GROUP BY nom
  5. HAVING avg(note) < 10

n°1608027
dodo
Posté le 04-09-2007 à 12:49:09  profilanswer
 

par contre il me semble que le group by doit comporter tout les champs du select, si je ne me trompes pas.

n°1608033
anapajari
s/travail/glanding on hfr/gs;
Posté le 04-09-2007 à 13:13:34  profilanswer
 

tu te trompes ;)

n°1608035
dodo
Posté le 04-09-2007 à 13:16:10  profilanswer
 

ok, merci de cette info

mood
Publicité
Posté le 04-09-2007 à 13:16:10  profilanswer
 

n°1608038
anapajari
s/travail/glanding on hfr/gs;
Posté le 04-09-2007 à 13:19:08  profilanswer
 

et puis surtout dans la requete de magic tous les champs du select sont dans le group by, Moyenne étant un alias de avg(note).

n°1608044
dodo
Posté le 04-09-2007 à 13:28:50  profilanswer
 

si j'ai dit ça c'est que j'avais fais un test et quand ne stipulant pas tout les champs du select dans le where cela n'avait pas fonctionner, mais peut être que j'avais une erreur ailleurs

n°1608046
anapajari
s/travail/glanding on hfr/gs;
Posté le 04-09-2007 à 13:35:25  profilanswer
 

en fait ça dépend des SGBDs, mais généralement c'est pas nécessaire.

n°1608072
MagicBuzz
Posté le 04-09-2007 à 14:26:50  profilanswer
 

La norme SQL stipule que le GROUP BY doit contenir AU MOINS TOUS les champs (y compris les calculs) SAUF les valeurs faisant l'objet d'une fonction d'agréga.
 
MySQL est un peu bourrin, il accepte qu'on ne les mette pas tous les champs. Dans ce cas, il n'y a aucun moyen de prévoir "à coup sûr" ce qu'il va faire, ceci dépendant uniquement de son interprétation personnelle : génération des regroupements manquants, récupèration de la première valeur des champs non regroupés, etc.
Il vaut donc mieux suivre ce que dit la norme, dans un souci de portabilité, et de garantie du résultat.
 
En fait, une fonction d'agrégat, c'est assez simple à comprendre comme ça marche : ça va faire un traîtement sur un group donné.
 
Par exemple :

Code :
  1. SELECT count(*) FROM matable


=> Ca va compter les lignes du groupe de lignes formée par l'ensemble des lignes de "matable".
 
Dans un cas où on a d'autres champs :

Code :
  1. SELECT count(*), nom FROM utilisateurs


Le count porte sur quoi ? Sur l'ensemble des lignes de la table utilisateur ? Sur chaque valeur différente de "nom" ? Aucune idée.
Pour cette raison, un SGBD classique va émettre une erreur et s'arrêter : c'est pas à lui de prendre ce genre de décisions.
La requête correcte sera donc :

Code :
  1. SELECT count(*), nom FROM utilisateurs GROUP BY nom


=> Pour chaque groupe identifié par une valeur unique de "nom", on a le nombre d'utilisateurs.
 
Mais que dire dans un cas de ce genre :
Table "produit" :


codpro  largeur  longueur hauteur  prix
A        10        10       10        10,00
B         5        20       10        15,00
C        10         2        5         8,00


 
Je veux connaître le prix moyen pour chaque volume de produit.

Code :
  1. SELECT avg(prix), largeur * longueur * hauteur FROM produit GROUP BY [euh... ?]


 
Réfléchissons...
 
Si je fais un "group by largeur, longueur, hauteur", puisque aucun de ces tuples n'est en double, je vais avoir 3 lignes. Pourtant, dans la colonne "volume", j'aurais bien 2 fois la même valeur (les produits A et B ont le même volume).
Le group by doit donc porter sur le calcul, et non les champs ! Ceci dit, on a le droit de l'écrire sous cette forme, car le regroupement reste valide, puisqu'on a énuméré la liste de tous les champs non agrégés.

Code :
  1. SELECT avg(prix), largeur * longueur * hauteur FROM produit GROUP BY largeur * longueur * hauteur


 
Enfin, le group by ne peut contenir d'alias. Il doit comporter l'expression exacte.
Ainsi ceci n'est pas valide en SQL, même si certains SGBD le supportent :

Code :
  1. SELECT avg(prix), largeur * longueur * hauteur volume FROM produit GROUP BY volume

Message cité 1 fois
Message édité par MagicBuzz le 04-09-2007 à 14:29:16
n°1608360
rufo
Pas me confondre avec Lycos!
Posté le 05-09-2007 à 09:22:38  profilanswer
 

MagicBuzz a écrit :


...
Enfin, le group by ne peut contenir d'alias. Il doit comporter l'expression exacte.
Ainsi ceci n'est pas valide en SQL, même si certains SGBD le supportent :

Code :
  1. SELECT avg(prix), largeur * longueur * hauteur volume FROM produit GROUP BY volume



 
Tiens, je savais pas ça. Sur Mysql, ça marche nickel et avec cette solution, j'aurais eu tendance à penser que les perfs sont meilleurs car le sgbd n'a pas besoin de recalculer l'expression spécifiée dans le group by :/

n°1608365
MagicBuzz
Posté le 05-09-2007 à 09:40:38  profilanswer
 

Si l'expression est la même, je doute qu'il la réévalue.
Par contre, je n'ai effectivement jamais pigé pourquoi on ne doit pas mettre d'alias, parceque le group by est de toute façon une requête plus ou moins post processing, c'est à dire qu'il ne peut être calculé qu'une fois l'ensemble des lignes trouvées et évaluées. Donc comme le order by, je ne vois pas pourquoi on ne peut pas mettre d'alias.
 
C'est du moins le cas avec Oracle, et si de tête, SQL Server supporte l'utilisation d'un alias, il n'est spécifié null part dans la doc qu'on peut les utiliser.
Impossible par contre de vérifier avec la norme véritable, car je n'arrive pas à mettre la main sur un lien.


Message édité par MagicBuzz le 05-09-2007 à 09:41:14
n°1608391
casimimir
Posté le 05-09-2007 à 10:38:07  profilanswer
 

truc très chiant d'ailleurs de ne pas pouvoir mettre d'alias dans le group by, du coup je remets souvent mon bloc dans un from ou je select et groupe au dessous ou alors c'est copier des case a rallonge dans le select et dans le group by, et a maintenir c'est la mert, personne n'est ceo d'oracle ici pour leur en toucher un mot?

n°1608394
MagicBuzz
Posté le 05-09-2007 à 10:40:35  profilanswer
 

chuis pas ceo, mais je peux donner la raison : "c'est d'la merde" :D

n°1608476
omega2
Posté le 05-09-2007 à 12:59:53  profilanswer
 

MagicBuzz > sql 92 : http://www.contrib.andrew.cmu.edu/ [...] ql1992.txt
Je n'ai pas regardé le document en détails mais d'après l'entête c'est la version normé "ISO/CEI 9075:1992" (9075 pour la norme SQL, le 92 pour l'année de la normalisation).
 
Bonne lecture. ;)

n°1608499
MagicBuzz
Posté le 05-09-2007 à 14:16:42  profilanswer
 


Syntax Rules
 
1) If no <where clause> is specified, then let T be the result of
   the preceding <from clause>; otherwise, let T be the result of
   the preceding <where clause>.
 
2) Each <column reference> in the <group by clause> shall unambigu-
   ously reference a column of T. A column referenced in a <group
   by clause> is a grouping column.
 
3) For every grouping column, if <collate clause> is specified,
   then the data type of the <column reference> shall be character
   string. The column descriptor of the corresponding column in the
   result has the collating sequence specified in <collate clause>
   and the coercibility attribute Explicit.


 
De ce que je comprends, donc...
- Ce sont des références aux "colonnes" du résultat de la requête. Par contre, ils parlent du résultat du FROM ou du WHERE, pas celui du SELECT. Hors c'est le SELECT qui amène les alias. Du coup, je me pose des questions : pas de fonctions, mais pas d'alias non plus. Ca me semble très biaisé, et on comprend pourquoi le SQL 1999 a été inventé si je comprends bien le truc.
- Ils ne disent pas explicitement que toutes les colonnes de la clause SELECT doivent se trouver dans la clause group by. Cependant, ils ne parlent pas non plus de fonctions d'agrégat. Et effectivement, un GROUP BY sans fonction d'aggrégat peut ne porter que sur un seul champ, ça marchera. En fait, je vais regarder du côté des fonctions d'aggrégat, je pense que c'est pas la définition de la clause GROUP BY qui contient la réponse ;)

n°1608508
MagicBuzz
Posté le 05-09-2007 à 14:30:51  profilanswer
 

D'après l'exemple page 617, c'est bien les colonnes non issues du SELECT qui sont utilisée.
 
Ainsi, :
 
SELECT count(*)
FROM ...
WHERE ...
GROUP BY untrucpasdansleselect
 
Est valide.
Ceci implique donc que j'ai raison en indiquant que le GROUP BY ne peut pas contenir d'alias.
Par contre, on dirait bien que le GROUP BY ne peut pas contenir de calculs, ce qui me semble étrange.
 
Ca voudrait dire qu'il est implossible d'avoir un truc du genre :
 
select count(*), hour(timestamp)
from log
group by hour(timestamp)
 
mais à la place :
 
select count(*), timestamp
from log
group by timestamp
 
ce qui à coup sûr, ne peut pas donner le même résultat !
 
 
Par contre, j'ai rien trouvé d'autre comme info...
 
Pour MIN() etc. ils ne parlent même pas de la clause (pourtant obligatoire) group by...


Message édité par MagicBuzz le 05-09-2007 à 14:31:52
mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  jointure dans le where ou dans le from

 

Sujets relatifs
[RESOLU] MySQL jointure sur clé primaire LENTEUtilisation requete php mysql contenant WHERE et AND
Requête complexe : probable jointure externe[MySQL] clause WHERE avec AS
Comment intégrer des valeurs de liste dans ma clause WHERE ? :(Jointure multiple
de l'utilité du "from t1 a , t1 b"[resolu]Jointure d'un COUNT dans une requête
[EXCEL]identifier et ramener titre colonne from contenu cellulesuppression plusieurs tables avec jointure
Plus de sujets relatifs à : jointure dans le where ou dans le from


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR