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


Sujet :

PHP & Base de données

  1. #1
    Membre régulier
    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)
    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)
    	";

  3. #3
    Membre régulier
    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

    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
    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
    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
    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
    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
    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
    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

    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
    Merci
    je vais tester

  13. #13
    Invité
    Invité(e)
    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 ?

  14. #14

  15. #15
    Invité
    Invité(e)
    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
    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

    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
    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
    pour continuer la discussion que j'a presque résolu j'ai créé un Nouveau Post https://www.developpez.net/forums/d1706049/php/php-sgbd/php-mysql/transmettre-variable-vue/#post9337399

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

  20. #20
    Membre régulier
    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