IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

temps infini pour une requête avec jointure [MySQL]


Sujet :

PHP & Base de données

  1. #1
    Membre régulier
    Inscrit en
    Avril 2004
    Messages
    496
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 496
    Points : 123
    Points
    123
    Par défaut temps infini pour une requête avec jointure
    Bonjour

    j'ai tenté la requête ci-dessous un Update avec une jointure sur une autre table, je ne comprends pas que ce soit avec un fichier php ou adapté à PhpMyAdmin la requête tourne sans donner de résultat.
    calcul du nombre de score supérieur dans la table des "donnes_players" à un score défini de la table "classement_donne"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    //mise à jour du NScoreSup dans classement_donne pour la donne 1
    $sql="UPDATE classement_donne AS cl
    INNER JOIN donnes_players AS dp
    ON dp.id_donnes=cl.id_donnes 
    SET NscoreSup=(SELECT COUNT(score) FROM donnes_players WHERE  dp.score>cl.score AND dp.id_donnes=cl.id_donnes)";
     
    $connexion->query($sql);
    par contre j'ai réalisé ce que je voulais avec des requêtes différentes là il faut 2 secondes pour mettre à jour(avec les affichages qui me permettent de contrôler)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    $sql="SELECT DISTINCT id_donnes FROM classement_donne";
    	$rep=$connexion->query($sql);
    	while ($donnees = $rep->fetch()){
    		echo 'id_donnes : '.$donnees['id_donnes']. '<br />';
    		$sql2="SELECT score FROM classement_donne WHERE id_donnes = ".$donnees['id_donnes'];
    			$rep2=$connexion->query($sql2);
    			while ($donnees2 = $rep2->fetch()){
    				echo 'score : '.$donnees2['score']. '<br />';
    				$sql3="SELECT COUNT(score)AS NBscoreSup FROM donnes_players WHERE  score>".$donnees2['score']." AND id_donnes=".$donnees['id_donnes'];
    					$rep3=$connexion->query($sql3);
    					while ($donnees3 = $rep3->fetch()){
    						echo 'NBscoreSup : '.$donnees3['NBscoreSup']. '<br />';
    						$sql4="UPDATE classement_donne SET NscoreSup =".$donnees3['NBscoreSup']." WHERE  score=".$donnees2['score']." AND id_donnes=".$donnees['id_donnes'];
     
    						$connexion->query($sql4);
     
    					}
    			}
    	}

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    ...Update avec une jointure sur une autre table...
    La jointure me semble mal placée.
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT COUNT(score) FROM donnes_players WHERE  dp.score>cl.score AND dp.id_donnes=cl.id_donnes
    A priori, cette partie est indépendante du reste de la requête. Or, il y manque des infos.

    Je ne suis pas sûr d'avoir tout capté, mais tente ça :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $sql = "UPDATE classement_donne AS cl1
    	SET NscoreSup = (SELECT COUNT(score)
    		FROM donnes_players AS dp2
    		INNER JOIN classement_donne AS cl2
    		ON dp2.id_donnes = cl2.id_donnes 
    		WHERE dp2.score>cl2.score AND dp2.id_donnes=cl2.id_donnes)
    	";
    Dernière modification par rawsrc ; 21/05/2017 à 14h19.

  3. #3
    Membre régulier
    Inscrit en
    Avril 2004
    Messages
    496
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 496
    Points : 123
    Points
    123
    Par défaut
    Bonsoir , je te remercie pour cette réponse

    malheureusement j'ai un message d'erreur
    Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'score' in field list is ambiguous' in C:\xampp\htdocs\testPHP\Bridgez\BaseDonnee\MiseAjourScorePlus_ClassementDonne.php:60 Stack trace: #0
    j'ai repris intégralement ton code

  4. #4
    Modérateur

    Avatar de MaitrePylos
    Homme Profil pro
    DBA
    Inscrit en
    Juin 2005
    Messages
    5 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : Belgique

    Informations professionnelles :
    Activité : DBA
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 496
    Points : 12 596
    Points
    12 596
    Par défaut
    Le message d'erreur est limpide, il ne sait pas sur quel score il doit faire le COUNT.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     
    SET NscoreSup = (SELECT COUNT(score)
    Il ne sait pas dans quelle table prendre le score :donnes_players AS dp2 ou classement_donne AS cl2

  5. #5
    Membre régulier
    Inscrit en
    Avril 2004
    Messages
    496
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 496
    Points : 123
    Points
    123
    Par défaut
    Il ne sait pas dans quelle table prendre le score :donnes_players AS dp2 ou classement_donne AS cl2
    pour moi c'est évident
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    (SELECT COUNT(score)
    		FROM donnes_players AS dp2
    moi je traduis comme ceci : compter les "score" de la table "donnes_players" alias "dp2"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WHERE dp2.score>cl2.score
    compter les score de dp2 où ils sont supérieurs au score de la table "classement_donne" alias cl2 qu'on retrouve avec la jointure entre les deux tables où elles ont toutes les deux le même "id_donne"

  6. #6
    Membre averti
    Homme Profil pro
    Autres
    Inscrit en
    Mai 2017
    Messages
    279
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Autres

    Informations forums :
    Inscription : Mai 2017
    Messages : 279
    Points : 421
    Points
    421
    Par défaut
    Ton problème se trouve dans ta sous-requête (SELECT) tes tables n'ont pas des alias. d'un cpoup dp et cl ne sont pas pris en compte.
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    //mise à jour du NScoreSup dans classement_donne pour la donne 1$sql="UPDATE classement_donne AS cl
    INNER JOIN donnes_players AS dp
    ON dp.id_donnes=cl.id_donnes 
    SET NscoreSup=(SELECT COUNT(score) FROM donnes_players AS dp, classement_donne AS cl WHERE  dp.score>cl.score AND dp.id_donnes=cl.id_donnes)";  $connexion->query($sql);
    L’appétit vient en mangeant.
    Pourquoi compliquer quand on peut faire plus simple?
    Une réponse vous a été utile? pensez à
    Vous avez eu la réponse à votre question? marquez votre discussion
    Faites un tour aux FAQs et aux tutoriels et cours.

  7. #7
    Membre averti
    Homme Profil pro
    Autres
    Inscrit en
    Mai 2017
    Messages
    279
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Autres

    Informations forums :
    Inscription : Mai 2017
    Messages : 279
    Points : 421
    Points
    421
    Par défaut
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    //mise à jour du NScoreSup dans classement_donne pour la donne 1
    $sql = "UPDATE classement_donne AS cl
        SET NscoreSup = (SELECT COUNT(score)
            FROM donnes_players AS dp
    INNER JOIN donnes_players AS dp
    ON dp.id_donnes=cl.id_donnes 
    SET NscoreSup=(SELECT COUNT(score) FROM donnes_players AS dp, classement_donne AS cl WHERE  dp.score>cl.score AND dp.id_donnes=cl.id_donnes)"; 
     $connexion->query($sql);

    Qu'est ce que ça donne @marco62118?
    L’appétit vient en mangeant.
    Pourquoi compliquer quand on peut faire plus simple?
    Une réponse vous a été utile? pensez à
    Vous avez eu la réponse à votre question? marquez votre discussion
    Faites un tour aux FAQs et aux tutoriels et cours.

  8. #8
    Membre régulier
    Inscrit en
    Avril 2004
    Messages
    496
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 496
    Points : 123
    Points
    123
    Par défaut
    je vais tester ta première réponse mais ta deuxième réponse est embrouillée il y a deux code mélangé

  9. #9
    Membre averti
    Homme Profil pro
    Autres
    Inscrit en
    Mai 2017
    Messages
    279
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Autres

    Informations forums :
    Inscription : Mai 2017
    Messages : 279
    Points : 421
    Points
    421
    Par défaut
    je l'ai modifié.regarde là ci-dessus.
    L’appétit vient en mangeant.
    Pourquoi compliquer quand on peut faire plus simple?
    Une réponse vous a été utile? pensez à
    Vous avez eu la réponse à votre question? marquez votre discussion
    Faites un tour aux FAQs et aux tutoriels et cours.

  10. #10
    Membre régulier
    Inscrit en
    Avril 2004
    Messages
    496
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 496
    Points : 123
    Points
    123
    Par défaut
    tu viens de faire une modif mais ce n'est pas encore clair
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (SELECT COUNT(score)
            FROM donnes_players AS dp
    INNER JOIN donnes_players AS dp
    la jointure est sur la même table
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SET NscoreSup = (SELECT COUNT(score)
            FROM donnes_players AS dp
    INNER JOIN donnes_players AS dp
    ON dp.id_donnes=cl.id_donnes 
    SET NscoreSup=(SELECT COUNT(score)
    et ici il y a deux fois le SET avec le SELECT

  11. #11
    Modérateur

    Avatar de MaitrePylos
    Homme Profil pro
    DBA
    Inscrit en
    Juin 2005
    Messages
    5 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : Belgique

    Informations professionnelles :
    Activité : DBA
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 496
    Points : 12 596
    Points
    12 596
    Par défaut
    Alors si pour toi c'est évident, ça l'est beaucoup moins pour ton moteur SQL.

    Tu dois simplement faire ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SELECT COUNT(dp2.score)
    		FROM donnes_players AS dp2

  12. #12
    Membre régulier
    Inscrit en
    Avril 2004
    Messages
    496
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 496
    Points : 123
    Points
    123
    Par défaut
    Merci
    je vais tester

  13. #13
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    j'efface tout, et je recommence...

    Column 'score' in field list is ambiguous'
    L'erreur signifie que dans COUNT(score), "score" est ambigu.

    Il faut préciser sur quelle table :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $sql = "UPDATE classement_donne AS cl1
    	SET NscoreSup = (SELECT COUNT(dp2.score)
    		FROM donnes_players AS dp2
    		INNER JOIN classement_donne AS cl2
    		ON dp2.id_donnes = cl2.id_donnes 
    		WHERE dp2.score>cl2.score AND dp2.id_donnes=cl2.id_donnes)
    	";
    Est-ce plus clair ?
    Dernière modification par Invité ; 22/05/2017 à 19h53.

  14. #14
    Modérateur

    Avatar de MaitrePylos
    Homme Profil pro
    DBA
    Inscrit en
    Juin 2005
    Messages
    5 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : Belgique

    Informations professionnelles :
    Activité : DBA
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 496
    Points : 12 596
    Points
    12 596
    Par défaut
    Heu j'ai rien dit d'autre.

  15. #15
    Invité
    Invité(e)
    Par défaut
    LOL, @MaitrePylos, je ne m'adressais (évidemment) pas à toi.

    Mais Nazoïde est venu... embrouiller les esprits avec un autre bout de code...

    Autant redonner le "bon" code, complet.

  16. #16
    Membre régulier
    Inscrit en
    Avril 2004
    Messages
    496
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 496
    Points : 123
    Points
    123
    Par défaut
    bonsoir

    me revoilà j'ai testé la nouvelle version mais rien y fait un nouveau message d'erreur
    Table 'cl1' is specified twice, both as a target for 'UPDATE' and as a separate source for data'
    j'ai fait toute sorte de test mais j'enchaîne les messages d'erreur.
    J'ai un peu de mal à comprendre pourquoi on appel parfois les mêmes tables avec des alias différents

    merci si vous pouvez encore m'aider

  17. #17
    Modérateur

    Avatar de MaitrePylos
    Homme Profil pro
    DBA
    Inscrit en
    Juin 2005
    Messages
    5 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : Belgique

    Informations professionnelles :
    Activité : DBA
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 496
    Points : 12 596
    Points
    12 596
    Par défaut
    Je suis désolé, je n'avais pas regarder la requête complètement.

    Tu peux essayer ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     
    "UPDATE classement_donne 
    	SET NscoreSup = (SELECT COUNT(dp2 . score)
    		FROM donnes_players AS dp2
    		INNER JOIN classement_donne AS cl2
    		ON dp2 . id_donnes = cl2 . id_donnes 
    		AND dp2 . score > cl2 . score)";

  18. #18
    Membre régulier
    Inscrit en
    Avril 2004
    Messages
    496
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 496
    Points : 123
    Points
    123
    Par défaut
    Bonsoir
    Désolé j'ai été absent quelques temps.

    malheureusement cette version ne change rien d'ailleurs à part la première ligne (AS dp1) rien ne change

    merci tout de même

  19. #19
    Membre régulier
    Inscrit en
    Avril 2004
    Messages
    496
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 496
    Points : 123
    Points
    123
    Par défaut
    pour continuer la discussion que j'a presque résolu j'ai créé un Nouveau Post https://www.developpez.net/forums/d1...e/#post9337399

    En espérant que vous pourrez encore m'apportez de l'aide.

  20. #20
    Membre régulier
    Inscrit en
    Avril 2004
    Messages
    496
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 496
    Points : 123
    Points
    123
    Par défaut
    Bonjour à toutes et tous

    j'ai enfin réussi à faire ce que je veux (faire un classement d'une donne précise) ce qui peut intéresser d'autres débutant
    départ: faire 2 COUNT "NscoreSup et NMemescore" sur une même colonne "score" d'une table avec des auto-jointures, pour utiliser ces 2 COUNT pour faire un classement.
    Ce qui est important c'est les différents GROUP BY des 2 auto-jointures et la première jointure LEFT et enfin le GROUP BY pour l'affichage
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    SELECT pl.pseudo, t1.score 
          ,((100*((@np:=(SELECT nbrePlayer FROM donnes WHERE id=1)-1) - COUNT(t2.id_players) - (0.5*(t3.NMemescore-1))))/(@np-1)) AS classement
    FROM (SELECT* FROM donnes_players WHERE id_donnes=1) AS t1
        LEFT JOIN (SELECT id_players,score,id_donnes FROM donnes_players WHERE id_donnes=1 group by id_players)AS t2	
        ON  t2.score>t1.score 
        INNER JOIN (SELECT id_players,score,id_donnes,COUNT(id_players) AS NMemeScore FROM donnes_players WHERE id_donnes=1 GROUP BY score)AS t3	
        ON  t3.score=t1.score 
        INNER JOIN (SELECT pseudo FROM players) AS pl
        ON t1.id_players=pl.id
    GROUP BY t1.id_players
    ORDER BY t1.score DESC ,pl.pseudo ASC
    Cette requête sera appelé par tous joueurs (un millier) pour voir son classement pour une donne précise avec id_donnes.
    Maintenant mon problème est la performance car cette requête s'exécute en plus de 2 secondes avec l'affichage.

    J'ai bien pensé aux Vues mais on ne peux pas passer de paramètres et là il me faut l'id_donnes que le joueur veut voir le classement.
    IL y a les requêtes préparées mais je ne vois pas bien la rapidité car juste avant d’exécuter la requête il faut transmettre l'id_donnes et tous les joueurs peuvent vouloir un classement d'une donne différente. Un même joueur ne fera appel au résultat de la requête qu'une fois par connexion à la base.
    Les requêtes stockées c'est la même chose à chaque fois qu'un joueur veut son classement il fournit l'id_donne qu'il veut consulter .

    Si Vous avez des pistes pour améliorer la performance merci d'avance

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Demande d'aide pour une requête avec jointure
    Par marcoxavier dans le forum Développement
    Réponses: 8
    Dernier message: 26/05/2015, 16h04
  2. Réponses: 11
    Dernier message: 15/09/2008, 10h25
  3. [MySQL] Cherche aide pour une requete avec jointure
    Par nasbe26 dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 29/09/2007, 11h44
  4. [ABAP] Comment créer une requête avec jointure
    Par roadster62 dans le forum SAP
    Réponses: 1
    Dernier message: 21/02/2006, 16h04
  5. optimisation d'une requête avec jointure
    Par champijulie dans le forum PostgreSQL
    Réponses: 8
    Dernier message: 07/07/2005, 09h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo