PHP|Débutant :: Forums

Advertisement

Besoin d'aide ? N'hésitez pas, mais respectez les règles

Vous n'êtes pas identifié(e).

#1 09-05-2012 20:22:22

ebouilleur
Membre
Lieu : Nantes
Inscription : 19-05-2009
Messages : 165
Site Web

Requete sql qui bug

Bonjour,

Je suis confronté a une erreur sql, dont je ne trouve pas le soucis.

Voici ma requete :

     
        INSERT INTO m_defis3 (id_defis, id_pseudo, id_employe_gagnant, invest_du_parieur, gain_du_parieur)
        SELECT p1.id_defis, p1.id_pseudo, d.employe_gagnant, p1.somme, calc_gain_parieur(p1.somme,p2.somme_mise_gagnant,p3.somme_mise_perdant)
         
        FROM defis_paris AS p1
        INNER JOIN defis AS d ON (p1.id_defis=d.id )    
        LEFT JOIN (
          SELECT sum(somme) as somme_mise_gagnant
          FROM defis_paris
          LEFT JOIN defis ON (defis_paris.id_employe=defis.employe_gagnant AND defis_paris.id_defis=defis.id)        
        ) AS p2 ON (p1.id_defis=p2.id_defis)
        LEFT JOIN (
          SELECT sum(somme) as somme_mise_perdant
          FROM defis_paris
          LEFT JOIN defis ON (defis_paris.id_employe!=defis.employe_gagnant AND defis_paris.id_defis=defis.id)
        ) AS p3 ON (p1.id_defis=p3.id_defis)        
        WHERE d.statut=5
 

L'erreur donnée par phpmyadmin est : #1054 - Unknown column 'p2.id_defis' in 'on clause'
Je comprend l'erreur, mais je ne vois pas pourquoi il me sert ca... id_defis existe bien dans la table defis_paris

Pour info m_defis3 est un table memory juste créé pour faire des calcules

Les autres tables sont :

--
-- Structure de la table `defis`
--

CREATE TABLE IF NOT EXISTS `defis` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `date_defis` datetime NOT NULL,
  `statut` tinyint(3) unsigned NOT NULL,
  `employe_gagnant` int(10) unsigned NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `etat` (`statut`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

-- --------------------------------------------------------

--
-- Structure de la table `defis_paris`
--

CREATE TABLE IF NOT EXISTS `defis_paris` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `id_defis` int(10) unsigned NOT NULL,
  `id_employe` int(10) unsigned NOT NULL,
  `id_pseudo` int(10) unsigned NOT NULL,
  `somme` smallint(5) unsigned NOT NULL,
  `jour` datetime NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `id_defis` (`id_defis`,`id_employe`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

-- --------------------------------------------------------

--
-- Structure de la table `defis_participant`
--

CREATE TABLE IF NOT EXISTS `defis_participant` (
  `id_defis` int(10) unsigned NOT NULL,
  `id_employe` int(10) unsigned NOT NULL,
  `id_pseudo` int(10) unsigned NOT NULL,
  `statut_employe` tinyint(3) unsigned NOT NULL,
  `lanceur` tinyint(3) unsigned NOT NULL,
  PRIMARY KEY  (`id_defis`,`id_employe`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

 

Enfin je pense que ma requete sql et l'erreur vous suffiront a m'aiguiller
merci d'avance smile

Dernière modification par ebouilleur (09-05-2012 20:22:39)

Hors ligne

#2 09-05-2012 20:29:09

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Requete sql qui bug

Bonjour,

L'erreur est simple. En effet la colonne de jointure doit être présente dans ton select, sinon elle ne peut se faire explicitement.


-- Voici la modification à faire concernant cette erreur
(
          SELECT id_defis, sum(somme) as somme_mise_gagnant
          FROM defis_paris
          LEFT JOIN defis ON (defis_paris.id_employe=defis.employe_gagnant AND defis_paris.id_defis=defis.id)        
        ) AS p2 ON (p1.id_defis=p2.id_defis)
 

tu as le même problème à corriger pour la requête dérivée suivante.

c'est le métier qui rentre wink

Dernière modification par Jc (09-05-2012 20:30:47)


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#3 09-05-2012 20:35:27

ebouilleur
Membre
Lieu : Nantes
Inscription : 19-05-2009
Messages : 165
Site Web

Re : Requete sql qui bug

Merci wink
il me manquait aussi un GROUP BY

Eh oui, j'essaye de réutiliser tout ce qu'on a vu ensemble, meme si des fois je m'enbrouille
Merci

Hors ligne

#4 11-05-2012 18:04:04

ebouilleur
Membre
Lieu : Nantes
Inscription : 19-05-2009
Messages : 165
Site Web

Re : Requete sql qui bug

Bonsoir,

Petite question JC (ou pour qui pourra me dire)

Quand je fais ce qu'on a vu ensemble, cad la création d'un table memory pour tout gérer, comment je peux faire pour faire un INSERT "précis".
je met tout le code mais seul le 2eme morceau me pose soucis :


  // création de la table memory pr les défis a réaliser
  $requete="CREATE TABLE `m_defis3` (
        `id` int(10) unsigned NOT NULL auto_increment,
        `id_defis` int(10) unsigned NOT NULL,
        `id_pseudo` int(10) unsigned NOT NULL,
        `id_gerant` int(10) unsigned NOT NULL,  
        `id_employe_gagnant` int(10) unsigned NOT NULL,
        `invest_du_parieur` int(10) unsigned NOT NULL,    
        `gain_du_parieur` int(10) unsigned NOT NULL,
        `gain_gerant` int(10) unsigned NOT NULL,
        PRIMARY KEY (`id`),
        KEY `idx_defis` (`id_defis`),
        KEY `idx_pseudo` (`id_pseudo`)    
      ) ENGINE=MEMORY DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci"
;
  $result = mysql_query($requete);
  if ($result===false){throw new Exception("Erreur de création de la table memory defis3",E_USER_NOTICE);}

  $sql7 = "INSERT INTO m_defis3 (id_defis, id_pseudo, id_gerant, id_employe_gagnant, invest_du_parieur, gain_du_parieur, gain_gerant)
          SELECT p1.id_defis, p1.id_pseudo, pm.id_pseudo, d.employe_gagnant, p1.somme, calc_gain_parieur(p1.somme,p2.somme_mise_gagnant,p3.somme_mise_perdant,d.employe_gagnant,p1.id_employe),
            (p3.somme_mise_perdant - (p3.somme_mise_perdant*90/100))          
          FROM defis_paris AS p1
          LEFT JOIN defis AS d ON (p1.id_defis=d.id )
          LEFT JOIN perso_masseur AS pm ON (pm.id=d.employe_gagnant )      
          LEFT JOIN (
            SELECT id_defis, sum(somme) as somme_mise_gagnant
            FROM defis_paris
            INNER JOIN defis ON (defis_paris.id_employe=defis.employe_gagnant AND defis_paris.id_defis=defis.id)
            GROUP BY defis_paris.id_defis        
          ) AS p2 ON (p1.id_defis=p2.id_defis)
          LEFT JOIN (
            SELECT id_defis, sum(somme) as somme_mise_perdant
            FROM defis_paris
            INNER JOIN defis ON (defis_paris.id_employe!=defis.employe_gagnant AND defis_paris.id_defis=defis.id)  
            GROUP BY defis_paris.id_defis        
          ) AS p3 ON (p1.id_defis=p3.id_defis)        
          WHERE d.statut=3
        "
;    
  $result = mysql_query($sql7);
  if ($result===false){throw new Exception("Erreur de remplissage de la table memory defis3",E_USER_NOTICE);}        
  if (mysql_affected_rows()>0){
 
    // on distribue les gains au parieurs
    $sqlUp = "UPDATE perso, m_defis3
              SET perso.argent=(perso.argent + m_defis3.gain_du_parieur)
              WHERE perso.id_pseudo=m_defis3.id_pseudo "
;
    $result = mysql_query($sqlUp);  
    if ($result===false){throw new Exception("MAJ argent gagnant du defi <br>$sqlUp<br>".mysql_error()."",E_USER_NOTICE);}
 
    // on distribue les gains au gérant
    $sqlUp = "UPDATE perso, m_defis3
              SET perso.argent=(perso.argent + m_defis3.gain_gerant)
              WHERE perso.id_pseudo=m_defis3.id_gerant "
;
    $result = mysql_query($sqlUp);  
    if ($result===false){throw new Exception("MAJ argent gérant du defi <br>$sqlUp<br>".mysql_error()."",E_USER_NOTICE);}
     
 

Et voila ce que j'arrive pas a faire. Peux etre qu'on ne peut tout simplement pas le faire comme ca ^^


    // msg pour le gagnant
    $msg_contenu = "Vous avez gagner un défi. Vous avez reçu : $gain_pr_gagant €.";

    $sqlUp = "INSERT INTO msg VALUES ('','20','Défi gagné','$msg_contenu','$jour_heure','0')
              WHERE msg.id_destinataire=m_defis3.id_gerant "
;
    $result = mysql_query($sqlUp);  
    if ($result===false){throw new Exception("MAJ argent gérant du defi <br>$sqlUp<br>".mysql_error()."",E_USER_NOTICE);}
 

Comment faire pour que $gain_pr_gagant est la valeur que je veux (et qui biensur est présente dans ma table m_defis3 ?

Merci

Hors ligne

#5 11-05-2012 18:17:57

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Requete sql qui bug

Bonjour,

Je suis passé en coup de vent, j'aurais plus de temps ce soir tard.
Si tu peux identifier de manière certaine le gagnant dans ta table memory dans un contexte où s'y trouvent plusieurs lignes (si une seule ligne aucun souci), tu peux faire un


INSERT INTO msg VALUES (champ1, champ2, champ3) SELECT lib1,lib2,lib3 FROM m_defis3 WHERE ....
 

++

Dernière modification par Jc (11-05-2012 21:37:41)


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#6 11-05-2012 18:21:09

ebouilleur
Membre
Lieu : Nantes
Inscription : 19-05-2009
Messages : 165
Site Web

Re : Requete sql qui bug

OK je vais tester ca, merci

Hors ligne

#7 11-05-2012 21:46:50

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Requete sql qui bug

Bonsoir,

ebouilleur a écrit :

Quand je fais ce qu'on a vu ensemble, cad la création d'un table memory pour tout gérer,

Tu m'attribues des dires ou des habitudes de dev qui ne sont pas les miennes. En effet, dans ce que l'on a déjà vu ensemble, j'ai dit que dans certains cas où il est nécessaire de contourner les problèmes de verrous dans certaines procédures transactionnées, la solution consiste à passer par une table de type memory. Il y a d'autres cas où il peut être très utile de les utiliser, comme table de mapping lors d'importation de données par exemple.
Pour ton cas de figure et selon tes besoins au niveau de l'interface et/ou fréquence de disponibilité des données pour l'essentiel (mais il y en a d'autres), il peut être préférable de passer par des vues SQL.

Il ne faut pas oublier que globalement il est nécessaire de faire en sorte que toute la base de données puisse être chargée en RAM serveur. A partir de là, utiliser des tables de type MEMORY peut être contre performant voire peser lourdement sur les performances de l'application dans certains cas de figure. Utiliser des tables MEMORY doit être et rester ponctuel dans un contexte maîtrisé.

De plus, une utilisation "intensive" de ces techniques dans un contexte de procédure transactionné peut avoir des effets de bords qui peuvent compliquer considérablement la gestion de ces tables. En effet, s'il est important de les détruire lorsque on en a plus besoin, les problèmes peuvent commencer à survenir lors d'accès concurrentiels important sur une procédure stockée qui utilise cette technique pour des besoins interne de production.

Développons un peu le contexte
Si par exemple en fin de procédure on détruit la table memory pour libérer les ressources et qu'au même moment un autre utilisateur l'utilise, (le nom utilisé est identique pour chaque utilisateur utilisant la procédure), il est impératif pour garantir l'intégrité, la qualité et la consistence des données de travailler alors dans un contexte SERIALIZABLE. Ceci va mettre les utilisateurs en file d'attente et ainsi chaque utilisateur créera sa propre table memory une fois que l'utilisateur précédent l'aura supprimée.

En résumé, il est important de bien réfléchir à ce que l'on fait et dans quel contexte on le fait pour éviter de mauvaises surprises. wink
++

Dernière modification par Jc (11-05-2012 21:56:54)


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#8 20-05-2012 15:43:56

ebouilleur
Membre
Lieu : Nantes
Inscription : 19-05-2009
Messages : 165
Site Web

Re : Requete sql qui bug

Oui oui, je suis bien concient de tout ca.
J'utilise une table memory ici, car c'est dans le même style que pour mes courses et mon cron, donc c'est pour ca que j'ai dis que j'ai fait comme tu m'avais conseillé wink
Je ne fais pas ca tout le temps ^^

Hors ligne

#9 20-05-2012 15:49:43

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Requete sql qui bug

ok tongue

Je profite pour rappeler le niveau d'isolation
Le niveau SERIALIZABLE vérouille entièrement les tables utilisées même en lecture
Le niveau juste en dessous qui est REPEATABLE-READ vérouille uniquement les lignes utilisées (à utiliser de préférence et à chaque fois que cela est possible).
Pour les niveaux moindre, je vous laisse regarder la doc^^.
++


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

Pied de page des forums