8796 sujets

Développement web côté serveur, CMS

Bonjour,

J'ai énormément de mal à trouver un tuto ou une doc correcte sur le case statement, du coup j'me retrouve avec des requêtes qui régulièrement ne fonctionnent pas. La dernière en date:

select id.ref_cat,rel.ref_bCat,id.nom,id.type,cg.outFocus
from cat_id id
inner join cat_status as st using (ref_cat)
left outer join cat_rel as rel using (ref_cat)
inner join
case id.type when b then bCat_config when s then sCat_config end
as cg using (ref_cat) where st.status!=0 order by rel.ref_bCat


Elle me renvoi:
#1064 - Erreur de syntaxe près de 'case id.type when b then bCat_config when s then sCat_config end' à la ligne 6

Et je ne parviens pas à la résoudre :s. Quelqu'un pourrait il m'aider à trouver l'erreur et à ne pas la reproduire?

Cordialement,

Smoke
Modifié par Smoke (13 Oct 2009 - 20:38)
Modérateur
Hello,

En lisant vite fait ( Smiley biggol ) et essayer de décortiquer ( Smiley sweatdrop ), je vois certaines choses qui vont pas :

* type est un mot me semble t'il qu'il faille éviter d'employer comme nom de champ. Si quelqu'un peut me confirmer ou me reprendre... D'ailleurs type de quoi ??? Smiley cligne

* FROM cat_id AS id
* ....
* INNER JOIN uneTable ON abbr.unChamp =
* J'ai la forte impression que tes conditions de jointures ne sont pas assez explicites.

Pour finir, je ne connais pas les critères, le contexte de ta requête ainsi que la structure de tes tables. Ça va être difficile de t'aider.
Modifié par Nolem (12 Oct 2009 - 17:49)
Salut Nolem et merci de ton attention Smiley smile

Okay pour type, j'attends comme toi confirmation, mais c'est aussi ce que je soupçonnais.

Théoriquement le AS pour les alias n'est pas obligatoire^^, et mysql retourne une erreur quand il y a un problème avec les alias^^ je doute que ce soit un soucis.

Je ne crois pas que le soucis soit sur les jointures^^ en tous cas pas sur celles en dehors du case. J'ai lu que if ne devait être utilisé que après select et après where, mais je n'ai pas confirmation de l'info, et je me demande si ça s'applique à case aussi.

Là je me réoriente vers une structure différente de requête, en virant le case, l'utiliser pour une jointure n'est peut être pas élégant, qu'en dis tu? Je fais donc un if pour le select, le soucis étant le suivant:

j'ai besoin en fonction du fameux type des enregistrements de faire une jointure entre deux tables différentes, l'une des deux ayant un champ de plus que l'autre, les champs en commun ayant le même nom. Vérifie du coup dans quelle table fouiller et quels champs récupérer, mon case devait me simplifier la tâche sur ça Smiley lol mais il l'a pas fait, donc bon...
Voici ma requête actuelle:

select id.ref_cat,rel.ref_bCat,id.nom,id.ctype,scg.outFocus,scg.onFocus
from cat_id id
left outer join cat_rel rel using (ref_cat)
left outer join sCat_config scg using (ref_cat)
left outer join cat_status st using (ref_cat)
#where st.status!='1'
order by ref_bCat[/code]

tel quel, elle fonctionne. Mais j'ai besoin que la clause where soit utilisée aussi, et avec celle que j'ai mise, elle me retourne des résultats erronnés :s. Je progresse donc, mais ce n'est pas encore ça.
Modérateur
En faisant un peu plus attention à ta sql, j'ai la forte impression que la ligne case...end n'a rien à faire là où elle est. Du coup, ta syntaxe est encore erronée : ...INNER JOINS AS cg...

Dans mes souvenirs CASE...END doit se placer :
* entre SELECT et FROM
ou
* après ON/WHERE

a écrit :

...
j'ai besoin en fonction du fameux type des enregistrements de faire une jointure entre deux tables différentes, l'une des deux ayant un champ de plus que l'autre, les champs en commun ayant le même nom.
...


J'ai la forte impression que ta base n'est pas normalisée. Est ce que tes données sont atomiques (suivant tes critères) ? As tu des clefs uniques ou composites ? Est ce que tes données et attributs sont redondants ?

a écrit :

...
Théoriquement le AS pour les alias n'est pas obligatoire^^, et mysql retourne une erreur quand il y a un problème avec les alias^^ je doute que ce soit un soucis.
...


En effet, il me semble bien et je ne m'en souvenais plus. J'ai pris pour habitude de l'écrire. Smiley smile

Comme je te l'ai dit précédemment, je ne comprend toujours pas le pourquoi de ta requête ? Aussi, je n'ai pas la structure de tes tables. Le mieux est que tu mettes sur le forum la requête à problème avec la structure de tables appelées.
La normalisation je découvre depuis peu Smiley langue , donc c'est assez loin d'être parfait. Voici ma structure:


CREATE TABLE IF NOT EXISTS `bCat_config` (
  `ref_cat` char(10) NOT NULL default '',
  `outFocus` char(14) default NULL,
  PRIMARY KEY  (`ref_cat`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;


CREATE TABLE IF NOT EXISTS `cat_id` (
  `ref_cat` varchar(10) NOT NULL default '',
  `ctype` enum('s','b') NOT NULL default 's',
  `nom` varchar(30) default NULL,
  `image` varchar(14) default NULL,
  `onFocus` varchar(14) NOT NULL default '',
  PRIMARY KEY  (`ref_cat`),
  KEY `type` (`ctype`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;



CREATE TABLE IF NOT EXISTS `cat_rel` (
  `ref_cat` char(10) NOT NULL default '',
  `ref_bCat` char(10) NOT NULL default '',
  PRIMARY KEY  (`ref_cat`),
  KEY `ref_bCat` (`ref_bCat`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;


CREATE TABLE IF NOT EXISTS `cat_status` (
  `ref_cat` char(10) NOT NULL default '',
  `status` enum('0','1') NOT NULL default '0',
  PRIMARY KEY  (`ref_cat`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;




CREATE TABLE IF NOT EXISTS `sCat_config` (
  `ref_cat` char(10) NOT NULL default '',
  `outFocus` char(14) default NULL,
  `onFocus` char(14) default NULL,
  PRIMARY KEY  (`ref_cat`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;


La requête suivante me renvoi ce qui m'intéresse:

select id.ref_cat,rel.ref_bCat,id.nom,id.ctype,scg.outFocus,scg.onFocus
from cat_id id
left outer join cat_rel rel on rel.ref_cat=id.ref_cat
left outer join sCat_config scg on scg.ref_cat=id.ref_cat
left outer join cat_status st on st.ref_cat=id.ref_cat
where st.status!='1'
order by ref_bCat


J'aurais voulu la faire plus élégante, et éviter des jointures inutiles^^ notamment sur la table bCat_config, qui contient le moins d'enregistrements.

Il se trouve que le USING m'a aussi posé quelques problèmes. Pas aussi simple à utiliser que je le pensais, je l'ai donc retiré purement et simplement^^

J'ai des clefs sur toutes les tables, la clef primaire se retrouve partout^^ (ref_cat), quelques index, et je ne crois pas avoir quoi que ce soit de redondant. En revanche, je ne comprends pas l'idée de 'données atomiques' :$
Modérateur
Smoke a écrit :

...
La requête suivante me renvoi ce qui m'intéresse:

select id.ref_cat,rel.ref_bCat,id.nom,id.ctype,scg.outFocus,scg.onFocus
from cat_id id
left outer join cat_rel rel on rel.ref_cat=id.ref_cat
left outer join sCat_config scg on scg.ref_cat=id.ref_cat
left outer join cat_status st on st.ref_cat=id.ref_cat
where st.status!='1'
order by ref_bCat


J'aurais voulu la faire plus élégante, et éviter des jointures inutiles^^ notamment sur la table bCat_config, qui contient le moins d'enregistrements.

Il se trouve que le USING m'a aussi posé quelques problèmes. Pas aussi simple à utiliser que je le pensais, je l'ai donc retiré purement et simplement^^

J'ai des clefs sur toutes les tables, la clef primaire se retrouve partout^^ (ref_cat), quelques index, et je ne crois pas avoir quoi que ce soit de redondant. En revanche, je ne comprends pas l'idée de 'données atomiques' :$


Donc logiquement ta conditionnelle devrait se trouver entre WHERE et ORDER. WHERE ... AND ... CASE ... END ORDER ...

Au passage, la syntaxe de cette requête est largement mieux. Smiley smile
Modifié par Nolem (12 Oct 2009 - 19:21)
Bin du coup le case n'a plus beaucoup de sens^^ puisque les champs concernés ne servent pas à la clause where^^

As tu des suggestions pour la rendre 'plus élégante'?
Salut,

J'ai lu en diagonale parce que c'est un peu long...

En tout cas c'est un peu illisible comme requête. Je te conseille de prendre le temps de bien (re)lire les tutos de http://sqlpro.developpez.com/

Nolem a écrit :
* type est un mot me semble t'il qu'il faille éviter d'employer comme nom de champ.
Non : cf. mots réservés mysql

Nolem a écrit :
* FROM cat_id AS id
AS est facultatif.
Merci Heyoan pour les précisions et le lien, ne le connaissant pas, je pense qu'il me sera très utile^^