JeuWeb - Crée ton jeu par navigateur
Problème dans une requête utilisant des alias - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Problème dans une requête utilisant des alias (/showthread.php?tid=5020)



Problème dans une requête utilisant des alias - Globe - 26-07-2010

Bonjour à tous, ces derniers temps j'essaye de rattraper un peu mes immenses lacunes et je découvre ainsi le joyeux monde des alias SQL. Mon erreur est probablement grossière mais bon je poste quand même. Alors pour essayer de comprendre le fonctionnement des alias j'ai essayé de retaper un code vieux de quelques années.

En gros grâce aux alias j'aimerais récupérer la valeur du champs nombre de d'une table j_batiments_joueurs pour trois entrées différentes caractérisées par le champs id_batiment. (la table se compose de id, id_joueur, id_batiment, nombre).

Voici ma requête :

Code :
                SELECT
                        batiments_fermes.nombre AS fermes,
                        batiments_bucherons.nombre AS bucherons,
                        batiments_carrieres.nombre AS carrieres
                   FROM
                        j_batiments_joueurs batiments_fermes,
                        j_batiments_joueurs batiments_bucherons,
                        j_batiments_joueurs batiments_carrieres
                   WHERE
                        id_joueur=".$_SESSION['id']."
                   AND
                        batiments_fermes.id_batiment = 1
                   AND
                        batiments_bucherons.id_batiment = 4
                   AND
                        batiments_carrieres.id_batiment = 5



RE: Problème dans une requête utilisant des alias - php_addict - 26-07-2010

ca te met quoi comme erreur?

a vu de nez et vu l'heure qu'il est c'est dans ton FROM que ca coince (sans vouloir etre vulgaire ;-))


RE: Problème dans une requête utilisant des alias - Globe - 26-07-2010

Fatal error: Call to a member function fetch() on a non-object in /homepages/15/d330192264/htdocs/ressources.php on line 38

Je stocke la requete dans la variable $req_bat_prod, elle est suivie de :
$req_bat_prod2 = $sql->query($req_bat_prod);
$bat_prod = $req_bat_prod2->fetch();

Et c'est le fetch qui pose problème, je passe par PDO et habituellement il m'envoit une erreur de ce type quand j'ai merdé dans la requête.


RE: Problème dans une requête utilisant des alias - Argorate - 26-07-2010

L'erreur est "simple" c'est que tu mets trois fois la meme table dans le FROM avec trois ALIAS différent. je vois pas pourquoi tu veux le faire comme ça Smile

Et si je peux me permetre un conseil, inutile de mettre un alias s'il est quasiment aussi long que le nom de la table, genre batiments_fermes tu met bf et sa suffit ^^ (je trouve ça plus lisible et moins long a écrire/utiliser.)

En l'occurence je vois pas l'utilité d'alias...

Donc pour récupere plusieurs entré il te faut faire comme suit:
Code :
SELECT
                        id_joueur, id_batiment, nombre AS nb,
                   FROM
                        j_batiments_joueurs
                   WHERE
                        id_joueur=".$_SESSION['id']."
                   AND
                        (
                           id_batiment = 1
                           OR
                           id_batiment = 4
                           OR
                           id_batiment = 5
                        )
Et tu obtiendra normalement (si elles existent) trois entrées.
Tu vas me dire "oué mais là je sais pas lequel corespond a quoi)

Bin si, l'id_batiment diferera a chaque fois, tu n'as plus qu'a faire dans le traitement qui récup ces données:

if(id_batiment == 1) ca corespond au cas "batiments_fermes"
elseif(id_batiment == 2) ..autres..
etc...

Tu vois?


RE: Problème dans une requête utilisant des alias - Globe - 26-07-2010

Bah le truc c'est que j'aimerais traiter les trois données en même temps. En fait me servir des infos pour faire des calculs, générer trois variables, et faire un update en utilisant les trois variables ainsi créée donc en gros stocker les trois informations dans des variables distinctes.


RE: Problème dans une requête utilisant des alias - Roworll - 26-07-2010

(26-07-2010, 01:13 AM)Argorate a écrit : L'erreur est "simple" c'est que tu mets trois fois la meme table dans le FROM avec trois ALIAS différent.

Ce genre de chose ne pose aucun problème pour les langages SQL.

L'erreur sur le Fetch signifie en effet que la requête à merdé.
Ne connaissant pas PDO, je ne sais pas si tu peux avoir un message d'erreur plus explicite mais cela aiderait certainement aux futurs débuggage.

Pour en revenir à ta requête d'origine, je pense que l'erreur se situe au niveau de la ligne id_joueur=".$_SESSION['id']."

Comme tu utilises trois fois la même table avec des alias si tu souhaites faire un WHERE sur le champ id_joueur, tu dois spécifier la table à utiliser sinon le moteur SQL est incapable de déterminer laquelle il doit utiliser. Tu peux mettre par exemple batiments_fermes.id_joueur=".$_SESSION['id'].". Cela devrait supprimer ton erreur mais ne renverra pas pour autant ce que tu attends (je te laisse tester toi même pour voir les résultats et essayer de comprendre ce qui se passe)

Le code donné par Argorate te renverra plusieurs lignes, une par bâtiment existant dans ta table. Au passage, personnellement, j'aurai remplacé la série de OR par id_batiment in (1,4,5).
L'avantage est que le résultat est renvoyé en une seule passe sur la base SQL. Le désavantage est que cela t'oblige à parcourir le recordset pour tester la valeur de id_batiment sur chaque ligne pour connaître précisément le type de bâtiment.

Maintenant, si tu souhaites tout avoir sur une seule ligne, je vois deux possibilités utiliser une jointure ou les sous requêtes.

La jointure est simple. A partir d'une table 'parent' tu vas joindre des tables 'filles' en reliant les lignes en fonction de certains champs/valeurs. Je te laisse chercher toi même les différences entre les jointures de type INNER et LEFT

Dans le code suivant, je pars d'une simple requête sur les fermes (alias bf) et je rajoute les informations sur les bucherons (alias bb) et les carrières (alias bc) avec des jointures. Petit inconvénient, si le joueur n'a pas de fermes (ma table 'parent'), tu n'auras aucun résultats en retour, même s'il possède des bucherons ou des carrières.
Code :
SELECT
   bf.nombre AS fermes,
   bb.nombre AS bucherons,
   bc.nombre AS carrieres
FROM
   j_batiments_joueurs bf
LEFT JOIN
   j_batiments_joueurs bb on bb.id_joueur = bf.id_joueur and bb.id_batiment = 4
LEFT JOIN
   j_batiments_joueurs bc on bc.id_joueur = bf.id_joueur and bb.id_batiment = 5
WHERE
   bf.id_joueur=".$_SESSION['id']."
AND
   bf.id_batiment = 1
Les moteurs SQL sont taillés pour travailler avec les jointures. Sur une bonne requête avec les bons index, les performances seront plus que correctes.

Les sous requêtes reviennent à faire plusieurs requêtes dans une seule.
Le moteur SQL va faire trois recherches dans la base de donnée et ranger le résultat dans un recordset.
Cela peut être un peu plus gourmand en ressources mais dans ton cas, cela devrait fonctionner selon tes attentes.
Code :
SELECT
   (
      SELECT nombre
      FROM  j_batiments_joueurs
      WHERE id_joueur=".$_SESSION['id']." AND
      id_batiment = 1
   ) as fermes,
   (
      SELECT nombre
      FROM  j_batiments_joueurs
      WHERE id_joueur=".$_SESSION['id']." AND
      id_batiment = 4
   ) as bucherons,
   (
      SELECT nombre
      FROM  j_batiments_joueurs
      WHERE id_joueur=".$_SESSION['id']." AND
      id_batiment = 5
   ) as carrieres



RE: Problème dans une requête utilisant des alias - niahoo - 26-07-2010

+1 avec le message d'au-dessus.

La syntaxe IN( int, [int, [...) est pas mal aussi pour s'éviter des multilignes OR x = x, OR x = x.
Sinon je pense qu'il te manquait la précision des tables.

Code :
SELECT
                        batiments_fermes.nombre AS fermes,
                        batiments_bucherons.nombre AS bucherons,
                        batiments_carrieres.nombre AS carrieres
                   FROM
                        j_batiments_joueurs batiments_fermes,
                        j_batiments_joueurs batiments_bucherons,
                        j_batiments_joueurs batiments_carrieres
                   WHERE
                        batiments_fermes.id_joueur=".$_SESSION['id']."
                 AND batiments_bucherons.id_joueur=".$_SESSION['id']."
                 AND batiments_carrieres.id_joueur=".$_SESSION['id']."
                   AND
                        batiments_fermes.id_batiment = 1
                   AND
                        batiments_bucherons.id_batiment = 4
                   AND
                        batiments_carrieres.id_batiment = 5

Par contre, tu nous à donné l'erreur renvoyée par PHP car tu appelais une méthode sur une variable qui n'était pas un objet.
Mais ce qui t'intéressait surtout c'était l'erreur renvoyée par le SGBD, pas celle de php.


RE: Problème dans une requête utilisant des alias - NicoMSEvent - 26-07-2010

le probleme a mon avis, est un ta variable : $_SESSION['id'] ... si elle est null, ta requete va merder ^^
Donc, soit tu met des simples guillements autour, soit tu teste ta valeur, et si elle est nulle, tu mets un beau zéro à la place Wink

A part ça, je ne vois de problème dans les requêtes (même si je n'aime pas la structure qu'elles ont)

Pour apporter ma pierre a l'édifice, j'aurais fait comme ça (plus simple a lire/maintenir)
L'avantage du bout de code ici, si n'importe lequel des batiment retourne un NULL, les autres batiments sont quand même affichés

SELECT
(SELECT nombre FROM j_batiments_joueurs WHERE id_joueur='".$_SESSION['id']."' AND id_batiment = 1) AS fermes, /*attention aux simples guillements ici*/
(SELECT nombre FROM j_batiments_joueurs WHERE id_joueur='".$_SESSION['id']."' AND id_batiment = 4) AS bucherons,
(SELECT nombre FROM j_batiments_joueurs WHERE id_joueur='".$_SESSION['id']."' AND id_batiment = 5) AS carrieres
FROM dual;



RE: Problème dans une requête utilisant des alias - Globe - 26-07-2010

Merci à tous. alors tout d'abord, j'avais déjà essayé de faire :

Code :
batiments_fermes.id_joueur=".$_SESSION['id']."
                 AND batiments_bucherons.id_joueur=".$_SESSION['id']."
                 AND batiments_carrieres.id_joueur=".$_SESSION['id']."

Ce qui me renvoyais la même erreur. J'avais également vérifié ce que renvoyait la requête et l'id de session est bien défini, j'avais d'ailleurs essayé avec et sans guillemets. En tout cas merci à tous vous m'avez apporté des solutions que je vais m'empresser de tester.