Dynamic SQL Error SQL error code = -104 invalid column refer

Eléphant du PHP | 97 Messages

12 juin 2006, 17:30

Bonjour,

J'ai un gros problème depuis 11H00.

Je ne parviens pas à faire un GROUP BY alors que je nomme bien le champ dans le SELECT. J'ai essayé plein de truc mais rien n'y fait.

J'ai en fait Deux tables :

JEUNE : CODE_JEUNE, PRENOM_JEUNE, NOM_JEUNE
ABSENCE_CONSTATEE : CODE_JEUNE, NB_CRENEAU, CODE_MOTIF_ABS

Je fais :
$Sql = "SELECT CODE_JEUNE, NOM_JEUNE, PRENOM_JEUNE
FROM ABSENCE_CONSTATEE INNER JOIN JEUNE ON ABSENCE_CONSTATEE.CODE_JEUNE = JEUNE.CODE_JEUNE
WHERE CODE_JEUNE < 10 GROUP BY CODE_JEUNE";

Dès que j'enlève GROUP_BY c ok mais malheureusement j'en ai besoin pour faire mes clalcul.

L'idée est de remonter la liste des Jeunes absence avec la somme de NB_CRENEAU qui correspond au cumul d'heure d'absence.

Merci à tous

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

12 juin 2006, 17:44

Essaye ça :

Code : Tout sélectionner

GROUP BY CODE_JEUNE, NOM_JEUNE, PRENOM_JEUNE

Invité
Invité n'ayant pas de compte PHPfrance

13 juin 2006, 08:51

ok ça marche.
mais je suis obligé de citer dans le GROUP BY tout les composant du SELECT ? car en ajoutant à ma requete des champs tel que :

Code : Tout sélectionner

SELECT CODE_JEUNE, NOM_JEUNE, PRENOM_JEUNE, CODE_GROUPE, NB_CRENEAU FROM ABSENCE_CONSTATEE INNER JOIN JEUNE ON ABSENCE_CONSTATEE.CODE_JEUNE = JEUNE.CODE_JEUNE WHERE CODE_JEUNE < 10 GROUP BY CODE_JEUNE, NOM_JEUNE, PRENOM_JEUNE
je suis obligé d'ajouter

Code : Tout sélectionner

GROUP BY CODE_JEUNE, NOM_JEUNE, PRENOM_JEUNE, CODE_GROUPE, NB_CRENEAU
pour que ça marche. Et ça fait n'importe quoi en fait.

Eléphant du PHP | 97 Messages

13 juin 2006, 08:55

en plus, le but ultime étant de faire une somme dans cette requete, je suis obligé de cité le champ NB_CRENEAU

Code : Tout sélectionner

SELECT JEUNE.CODE_JEUNE, JEUNE.PRENOM_JEUNE, JEUNE.NOM_JEUNE, ABSENCE_CONSTATEE.NB_CRENEAU, SUM(ABSENCE_CONSTATEE.NB_CRENEAU) AS NOMBRE FROM ABSENCE_CONSTATEE INNER JOIN JEUNE ON ABSENCE_CONSTATEE.CODE_JEUNE = JEUNE.CODE_JEUNE GROUP BY JEUNE.NOM_JEUNE

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

13 juin 2006, 09:14

C'est de la logique, si tu veux grouper tes résultats selon certains champs, pour chaque ligne retournée, les champs qui ne sont pas dans la clause GROUP BY peuvent contenir plusieurs valeurs.

Donc doit ta groupement n'est pas valide, soit tu as mal modelisé ta base
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Eléphant du PHP | 140 Messages

13 juin 2006, 09:17

Bon, ce n'est pas normal d'avoir a lister autant de choses dans le GROUP BY...

Donc plusieurs questions et remarques :

1/ Pourquoi fais-tu un INNER JOIN ? Ce n'est absolument pas INNNER JOIN que tu decris mais bien un OUTER JOIN... Donc mets-donc un bete JOIN, ca devrait marcher.

2/ GROUP BY CODE_JEUNE n'a pas de sens... cela fait reference a 2 colonnes distinctes (meme si theoriquement elles ont la meme valeur). De maniere generale il faut toujours respecter 2 regles :
- donner des alias aux tables ... FROM Jeune J
- nommer les tables des colonnes SELECT J.CODE_JEUNE

Au final, je pense que virer ton OUTER JOIN resoudra le probleme... mais je te conseille de faire aussi attention au 2nd point.

Invité
Invité n'ayant pas de compte PHPfrance

13 juin 2006, 09:30

ok pour les alias mais encore une fois :

Code : Tout sélectionner

$Sql = "SELECT j.CODE_JEUNE, j.NOM_JEUNE, j.PRENOM_JEUNE FROM ABSENCE_CONSTATEE a, JEUNE j WHERE j.CODE_JEUNE < 10 GROUP BY j.CODE_JEUNE, j.NOM_JEUNE, j.PRENOM_JEUNE";
ça fonctionne alors que :

Code : Tout sélectionner

$Sql = "SELECT j.CODE_JEUNE, j.NOM_JEUNE, j.PRENOM_JEUNE FROM ABSENCE_CONSTATEE a, JEUNE j WHERE j.CODE_JEUNE < 10 GROUP BY j.CODE_JEUNE, j.NOM_JEUNE";
ne fonctionne pas.

alors je ne suis pas prêt d'y ajouter un SUM sur le champs NB_CRENEAU

Eléphant du PHP | 97 Messages

13 juin 2006, 09:32

d'ailleur,
$Sql          = "SELECT 
                 j.CODE_JEUNE, j.NOM_JEUNE, j.PRENOM_JEUNE,
				 SUM(a.NB_CRENEAU) AS heures
				 FROM ABSENCE_CONSTATEE a, JEUNE j
			 	 WHERE j.CODE_JEUNE < 10 
				 GROUP BY j.CODE_JEUNE, j.NOM_JEUNE, j.PRENOM_JEUNE, heures";
me donne encore une erreur alors que je cite tous les champs.
Vraiment je pédale à fond ici. :?

Eléphant du PHP | 140 Messages

13 juin 2006, 09:35

Mais, ca ne dispense pas de mettre un JOIN. Dans la requete du dessus il te fallait virer ton INNER JOIN et le remplacer par un LEFT JOIN par exemple.

Eléphant du PHP | 97 Messages

13 juin 2006, 09:45

Bonjour et merci de ton intervention.

Les jonctions ne peuvent elles pas se créer aussi en ajoutant une simple WHERE clause qui indique a.CODE_JEUNE = j.CODE_JEUNE ?

tel que :
$Sql          = "SELECT 
                 j.CODE_JEUNE, j.NOM_JEUNE, j.PRENOM_JEUNE,
				 SUM(a.NB_CRENEAU) AS heures
				 FROM ABSENCE_CONSTATEE a, JEUNE j
			 	 WHERE j.CODE_JEUNE < 10 AND a.CODE_JEUNE = j.CODE_JEUNE 
				 GROUP BY j.CODE_JEUNE, j.NOM_JEUNE, j.PRENOM_JEUNE, heures";

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

13 juin 2006, 09:54

on dit jointure et non pas jonction

Si, tu peut joindre des tables dans la clause WHERE mais il me semble que, sous MySQL, l'optimisation est meilleure avec un JOIN
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Eléphant du PHP | 140 Messages

13 juin 2006, 10:14

Si, tu peut joindre des tables dans la clause WHERE mais il me semble que, sous MySQL, l'optimisation est meilleure avec un JOIN
C'est surtout que sans jointure tu ne peux pas faire de GROUP BY. Le controleur syntaxique s'apercoit en effet qu'il a un select sur 2 tables :S

Au final ta requete devrait reseembler a

Code : Tout sélectionner

SELECT a.CODE_JEUNE, j.NOM_JEUNE, j.PRENOM_JEUNE, SUM(a.NB_CRENEAU) AS heures FROM ABSENCE_CONSTATEE a LEFT JOIN JEUNE j ON a.CODE_JEUNE = j.CODE_JEUNE WHERE j.CODE_JEUNE < 10 GROUP BY a.CODE_JEUNE;

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

13 juin 2006, 10:28

si, il y a une jointure.

Quand tu fait

Code : Tout sélectionner

SELECT a.1, a.2, b.1 FROM a JOIN b ON a.id = b.id
c'est équivalent à

Code : Tout sélectionner

SELECT a.1, a.2, b.1 FROM a, b WHERE a.id = b.id
Je peut même te dire que sous Oracle, la 2nd solution est beacoup mieux intégrée dans l'arbre d'optimisation que la 1ere, surtout quand tu as des clés primaires portant sur plusieurs champs ;)
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Eléphant du PHP | 140 Messages

13 juin 2006, 10:41

si, il y a une jointure.
Je ne dis pas qu'il n'y a pas jointure :wink: juste que l'analyseur SQL ne reconnait pas systematiquement la jointure si elle n'est pas complete (FULL JOIN).
Et au final, s'il ne la reconnait pas, tu ne peux pas faire de GROUP BY.

Maintenant Oracle est certainement beaucoup plus intelligent que beaucoup de RDBMS. :D

Eléphant du PHP | 97 Messages

13 juin 2006, 11:57

Si, tu peut joindre des tables dans la clause WHERE mais il me semble que, sous MySQL, l'optimisation est meilleure avec un JOIN
C'est surtout que sans jointure tu ne peux pas faire de GROUP BY. Le controleur syntaxique s'apercoit en effet qu'il a un select sur 2 tables :S

Au final ta requete devrait reseembler a

Code : Tout sélectionner

SELECT a.CODE_JEUNE, j.NOM_JEUNE, j.PRENOM_JEUNE, SUM(a.NB_CRENEAU) AS heures FROM ABSENCE_CONSTATEE a LEFT JOIN JEUNE j ON a.CODE_JEUNE = j.CODE_JEUNE WHERE j.CODE_JEUNE < 10 GROUP BY a.CODE_JEUNE;
Ok mais : Dynamic SQL Error SQL error code = -104 invalid column reference in

et dès que je modifie avec les noms des champs :
Dynamic SQL Error SQL error code = -206 Column unknown HEURES

$Sql          = "SELECT a.CODE_JEUNE, j.NOM_JEUNE, j.PRENOM_JEUNE, SUM(a.NB_CRENEAU) AS heures 
FROM ABSENCE_CONSTATEE a
LEFT JOIN JEUNE j  ON a.CODE_JEUNE = j.CODE_JEUNE 
WHERE j.CODE_JEUNE < 10
GROUP BY a.CODE_JEUNE, j.NOM_JEUNE, j.PRENOM_JEUNE, heures;";