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

Mammouth du PHP | 1353 Messages

13 juin 2006, 11:59

Petit détail : je pense qu il faut enlever le ; à la fin de la requete :D
Tell me and I forget. Teach me and I remember. Involve me and I learn.

Eléphant du PHP | 97 Messages

13 juin 2006, 12:13

non cela ne change rien :
$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";
Warning: ibase_query() [function.ibase-query]: Dynamic SQL Error SQL error code = -104 invalid column reference in D:\www\site\cfa\ymag_absences.php on line 100

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

13 juin 2006, 12:58

les béabas du group by:
Un group by effectue un regroupement de lignes selon les champs spécifiés dans le select.

Si dans mysql ce n'est pas obligatoire, les autres SGBD et SQL standard l'exigent et c'est tout à fait logique.
Car on peut choisir l'ordre de regroupement des lignes en choisissant l'ordre des champs de regroupement (champs figurant dans le select)
et que l'ordre de regroupement n'est pas forcement celui de la structure du résultat (select).

Il faut noter aussi que les champs calculés ne doivent pas figurer dans le group by

Ta requête alors doit être:

Code : Tout sélectionner

SELECT j.CODE_JEUNE, j.NOM_JEUNE, j.PRENOM_JEUNE, SUM(a.NB_CRENEAU) AS heures FROM JEUNE j INNER JOIN ABSENCE_CONSTATEE a ON a.CODE_JEUNE = j.CODE_JEUNE WHERE j.CODE_JEUNE < 10 GROUP BY j.CODE_JEUNE, j.NOM_JEUNE, j.PRENOM_JEUNE
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Eléphant du PHP | 97 Messages

13 juin 2006, 13:38

Merci, ça marche impec.
Mais par contre je ne peux pas ajouter d'autres champs !
car si je veux "a.CODE_MOTIF_ABS, a.CODE_GROUPE" dans le select mais pas dans le group by j'ai aussi une erreur.

Code : Tout sélectionner

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

Eléphant du PHP | 140 Messages

13 juin 2006, 14:04

les béabas du group by:
Un group by effectue un regroupement de lignes selon les champs spécifiés dans le select.

Si dans mysql ce n'est pas obligatoire, les autres SGBD et SQL standard l'exigent et c'est tout à fait logique.
Euh... je ne suis pas certain :?
Je viens de faire le test sur un Oracle 10g et je n'ai pas eu besoin de le faire. Tu es sur que c'est necessaire systematiquement ?

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

13 juin 2006, 14:09

Je viens de faire le test sur un Oracle 10g et je n'ai pas eu besoin de le faire. Tu es sur que c'est necessaire systematiquement ?
:shock: sous Oracle 10g, si les champs du GROUP By ne sont pas pas tous dans le SELECT, il y a une erreur retournée
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, 14:13

:shock: sous Oracle 10g, si les champs du GROUP By ne sont pas pas tous dans le SELECT, il y a une erreur retournée
Pas sur le serveur ou je bosse :?
Peut-etre est-il configuré d'une maniere particuliere ?

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

13 juin 2006, 14:14

Je trouve ça extremement bizarre vu qu'on touche à la nomr SQL/ANSI quand même

Quelle est la requete que tu as essayé ?
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

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

13 juin 2006, 14:31

À l'origine je ne voulais poster que pour conseiller à coolhead d'éviter de tout écrire en majuscule, et en particulier le nom des champs PARCE QUE C'EST SUPER DIFFICILE À LIRE ET ON NE VOIT OÙ SONT LES MOTS IMPORTANTS. C'est une habitude que je vois essentiellement chez ceux qui travaillent sur Oracle, est-ce que quelqu'un sait pourquoi ?

À part ça, je suis nul niveau Oracle, mais d'après ce que je me rappelle la base est assez laxiste face aux "GROUP BY" partiels (où tous les champs SELECT ne sont pas couverts par le GROUP BY ou une fonction d'aggrégation) et ne déclenchera pas d'erreur si le résultat est identique avec ou sans un GROUP BY complet. Autrement dit, si la requête n'est pas bonne mais que ça n'affecte pas le résultat alors rien ne se passe. Je ne l'ai pas vérifié, c'est juste ce que je me rappelle d'une conversation antérieure.

Invité
Invité n'ayant pas de compte PHPfrance

13 juin 2006, 14:41

Je trouve ça extremement bizarre vu qu'on touche à la nomr SQL/ANSI quand même

Quelle est la requete que tu as essayé ?
:pouce: effectivement zeus, moi et toi on parle de standard SQL mais les autres parlent de spécificité de SGBD.

De toutes façons, les erreurs ne pourraient se résoudre que si on se conforme d'abord aux normes et qu'on comprenne les notions de base et par la suite optimiser le comment-faire.

Par exemple, pour que le regroupement soit cohérent, il faut :
1. au moins une table centrale où le calcul doit être effectué sur un lot d'enregistrements ayant des caractères communs (doublons de valeurs de champs) tel que des index avec doublons ou des clés étrangères

2. si le regroupement doit s'étendre sur plusieurs tables, les jointures entre la table centrale de travail et les autres doivent être définies dans un ordre logique

3. La clause select décide de la structure du résultat (liste de champs + calculs)

4. La clause From définit la source principale du travail ainsi que les sources annexes qui lui sont liées

5. la clause group by définit l'ordre de critères de regroupement (ordre des champs définits dans le select sur lequel le tri des lignes sera effectué pour traiter les calculs)
L'orde des champs dans le group by n'est pas forcement le même de celui du select
La clause Having définit les critères de filtrage au moment du regroupement. Cette clause est annexée au Group By et remplace le Where du select.

Eléphant du PHP | 97 Messages

13 juin 2006, 14:54

Pour ma part je suis en INTERBASE et les champs sont bien en majuscule sous IB.

Par contre par rapport à ma question, bien évidement je ne souhaite pas intégrer les champs supplémentaires "CODE_GROUPE", "CODE_MOTIF_ABS" dans le GROUP BY mais je veux pouvoir les lire par la suite et donc les avoir dans le SELECT.

Je en comprends pas pourquoi je ne peux partir de :
$Sql          = "SELECT j.CODE_JEUNE, j.NOM_JEUNE, j.PRENOM_JEUNE, 
SUM(a.NB_CRENEAU) AS heures 
FROM JEUNE j 
INNER JOIN  ABSENCE_CONSTATEE a  ON a.CODE_JEUNE = j.CODE_JEUNE 
WHERE j.CODE_JEUNE < 10 
GROUP BY  j.CODE_JEUNE, j.NOM_JEUNE, j.PRENOM_JEUNE";
et ajouter ", a.CODE_GROUPE, a.CODE_MOTIF_ABS" dans le SELECT pour les lire.

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

13 juin 2006, 15:22

Puisque Ibase respecte donc le standard du Group by, tu ne peux que t'y incliner cher ami.
Ta requête devient :
$Sql          = "SELECT j.CODE_JEUNE, j.NOM_JEUNE, j.PRENOM_JEUNE, 
a.CODE_GROUPE, a.CODE_MOTIF_ABS, SUM(a.NB_CRENEAU) AS heures 
FROM JEUNE j 
INNER JOIN  ABSENCE_CONSTATEE a  ON a.CODE_JEUNE = j.CODE_JEUNE 
WHERE j.CODE_JEUNE < 10 
GROUP BY  j.CODE_JEUNE, j.NOM_JEUNE, j.PRENOM_JEUNE, a.CODE_GROUPE, a.CODE_MOTIF_ABS"; 	
ce qui est tout à fait logique, puisque cette requête regroupe le résultat par jeune et par code_groupe et motif avant de calculer la somme de nb_creneau
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

13 juin 2006, 15:28

Le problème c'est que plusieurs valeurs de CODE_GROUPE ou CODE_MOTIF_ABS peuvent exister dans chaque groupe, quelle valeur utiliser alors ? si tu les veux toutes je ne vois pas d'autre moyen que de les ajouter dans le GROUP BY, auquel cas la valeur de "heures" s'en verra modifiée. Ou alors tu mets la requête actuelle dans une table dérivée (ou "vue temporaire") et tu fais une jointure sur la table d'absences

Code : Tout sélectionner

SELECT tmp.CODE_JEUNE, tmp.NOM_JEUNE, tmp.PRENOM_JEUNE, tmp.heures, abs.CODE_GROUP, abs.CODE_MOTIF_ABS FROM ( SELECT j.CODE_JEUNE, j.NOM_JEUNE, j.PRENOM_JEUNE, SUM(a.NB_CRENEAU) AS heures FROM JEUNE j INNER JOIN ABSENCE_CONSTATEE a ON a.CODE_JEUNE = j.CODE_JEUNE WHERE j.CODE_JEUNE < 10 GROUP BY j.CODE_JEUNE, j.NOM_JEUNE, j.PRENOM_JEUNE ) AS tmp INNER JOIN ABSENCE_CONSTATEE abs ON abs.CODE_JEUNE = tmp.CODE_JEUNE
moi et toi on parle de standard SQL mais les autres parlent de spécificité de SGBD
Malheureusement, il y a un moment où il faut prendre en compte les réalités du monde qui nous entoure. Il n'est pas toujours possible de programmer avec des œillères et suivre aveuglément les standards. Je suis le premier à réclamer un plus grand respect des standards, mais il faut se rendre à l'évidence : à la fin, on programme toujours pour une SGBD particulier. En tout cas, jusqu'à ce que l'ISO développe son propre logiciel ou que Fabian Pascal frotte une lampe à génie.

Eléphant du PHP | 97 Messages

13 juin 2006, 15:35

En effet je n'avais pas pensé à ça.
En fait le "CODE_GROUPE" doit toujours être le même.

Mais là où je n'avais pas prévu el clash, c'est pour "CODE_MOTIF_ABS" qui est une valeur "O" ou "N" me permettant de faire le différence entre les abscences justifié et les les absences non-justifié.

Je ne peux donc pas créer une seule requete qui me remonte avec "NB_CRENEAU" la somme d'absence et y ajouter deux champs qui serait "heures_just" et "heures_non_just" dans lesquel je metterait la somme de "NB_CRENEAU" ou "CODE_MOTIF_ABS" = "O" et l'autre avec la somme de "NB_CRENEAU" ou "CODE_MOTIF_ABS" = "N".

Ok j'abandonne.
En plus le "CODE_MOTIF_ABS" n'est pas vraiment OUI ou NON mais uen valeur à lire dans une autre tables ayant un champ "ABS_JUSTIFIEE" qui peut être à "O" ou "N".

:? :(

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

13 juin 2006, 15:43

C'est une habitude que je vois essentiellement chez ceux qui travaillent sur Oracle, est-ce que quelqu'un sait pourquoi ?
Simplement parce que oracle retourne tout les champs en majuscule donc depuis n'importe quel visualiseur de BdD, tu as les noms des champs en majuscule.

Et comme on a tendance a copier ce qu'on voit, on copie en majuscule

Il n'y a que dans mes requetes PHP (qui vont rester en dur) que je met que les instructions SQL en majuscule pour des raisons de lisibilité
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