Version complète: sur le forum Webmaster Hub : Ex-aequo dans table
Webmaster Hub > Création et exploitation de Sites Internet > Les langages du Net > SQL
Didier M
Bonjour,

J'utilise cette requète pour afficher les places de compétitions, mais le problème est le traitement des exeaquo, en effet la requète me donne par exemple :

1
2
4
4
5

Et il faudrait
1
2
3
3
5

La requète

CODE
$req = mysql_query("SELECT *, (SELECT COUNT(*) FROM danseurs_$Saison WHERE Catégorie='$Catégorie' AND valid<>'x' AND Total_points >= ge.Total_points) as place FROM danseurs_$Saison ge WHERE Catégorie='$Catégorie' AND valid<>'x' ORDER BY Total_points DESC") or die ('Erreur SQL 1!'.$req.'<br>'.mysql_error());


merci pour votre aide
Dadou
rien compris
MagNet
Pas compris non plus.

Tu veux remplacer les 4 par des 3 ? Il faut faire un update SQL.
captain_torche
Si j'ai bien compris, il veut faire une gestion des ex-eaquo (si deux notes sont les mêmes, les deux postulants on le même classement, et on saute ensuite 1 résultat pour continuer le classement).
Pour cela, je ne pense pas qu'on puisse le faire directement en SQL, un travail en PHP devrait être nécessaire.
Kioob
si si. Dans l'idée :
CODE
select joueur_id, 1+count(b.points) as position
from joueurs a
    left join joueurs b on a.points < b.points
group by a.joueur_id
order by position desc, joueur_id asc



edit : j'avais oublié le "group by"...
petit-ourson
Je le ferai à travers une procédure stockée moi.
Didier M
Bonjour,

Captain à compris ce que je voulais faire, l'ordre des places est en fonction d'un nombre de points qui sont enregistrés dans mysql,
cela me sers à faire un classement général en fonction des points.

Voici un lien pour un classement :Classement

Donc la place de 7 devrait être 6 et on passe directe à 8.


je regarde ce que donne la requéte postée plus haut, merci.
Didier M
Bon, je viens d'essayer la requète de kioob, cela ne fonctionne pas sad.gif

Une idée ?

Merci.
Kioob
mmm soit j'ai fait une petite erreur en l'écrivant (de tete), soit tu en as fais une en adaptant. Mais cela fonctionne, j'en suis persuadé.

J'ai utilisé ce genre de requêtes pendant des années.


EDIT : donc je viens de tester sur une vieille table, et mis à part l'order by un peu foireux (la liste est à l'envers), ça fonctionne parfaitement.
petit-ourson
Bon ça restera peut être juste un cas d'école...

Soit la table :
CODE
mysql> select * from danseurs
+-----------+------+--------+
| idDanseur | nom  | points |
+-----------+------+--------+
|         1 | Toto |     10 |
|         2 | Tata |    100 |
|         3 | Titi |     50 |
|         4 | Tutu |     20 |
|         5 | Tete |     50 |
+-----------+------+--------+


Soit la procédure stockée :
CODE
CREATE PROCEDURE Classement()
    NOT DETERMINISTIC
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN

        DECLARE var_id INT;
        DECLARE var_nom VARCHAR(100);
        DECLARE var_points INT;
        
        DECLARE var_position INT DEFAULT 0;
        DECLARE var_numero INT DEFAULT 0;

        DECLARE var_pointprecedent INT DEFAULT NULL;
        

        DECLARE done INT DEFAULT 0;
        DECLARE curseur1 CURSOR FOR SELECT * FROM danseurs ORDER BY points DESC;
        DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;

        DROP TEMPORARY TABLE IF EXISTS TempDanseurs;
        CREATE TEMPORARY TABLE TempDanseurs (
        idDanseur INT NOT NULL PRIMARY KEY,
        nom VARCHAR(100) NOT NULL,
        points INT NOT NULL,
        position INT NOT NULL
        ) ENGINE=MEMORY;

        OPEN curseur1; # ouverture du curseur1

        REPEAT
                FETCH curseur1 INTO var_id, var_nom, var_points;
                IF done = 0 THEN

                        SET var_numero := var_numero + 1;
                
                        IF( var_pointprecedent IS NULL OR var_points < var_pointprecedent) THEN
                            SET var_position := var_numero;
                        END IF;
            
                        SET var_pointprecedent := var_points;
            
                        INSERT INTO TempDanseurs(idDanseur, nom, points, position) VALUES (var_id, var_nom, var_points, var_position);

                END IF;

        UNTIL done
        END REPEAT;

        CLOSE curseur1; # fermeture du curseur1

        SELECT * FROM TempDanseurs ORDER BY position;
        
END|


Le résultat :
CODE
mysql> CALL Classement();
+-----------+------+--------+----------+
| idDanseur | nom  | points | position |
+-----------+------+--------+----------+
|         2 | Tata |    100 |        1 |
|         5 | Tete |     50 |        2 |
|         3 | Titi |     50 |        2 |
|         4 | Tutu |     20 |        4 |
|         1 | Toto |     10 |        5 |
+-----------+------+--------+----------+


Si quelqu'un me trouve comment me passer de la table temporaire... Je n'ai pas trouvé.
Didier M
Merci petit ourson, mais ouf c'est pas simple comme manip, j'essaye la solution de Kioob et encore merci pour ta solution.


Merci Kioob pour la réponse, je pense mettre trompé dans ta requète,

Donc j'aie un table qui s'apelle danseur_$Saison, dans laquelle j'aie Dossards (id), Total_points, Catégorie, valid.

Je modifie ta requète :

CODE
select Dossards, 1+count(b.Total_points) as place
from danseur_$Saison a
    left join danseur_$Saison b on a.Total_points < b.Total_points
group by a.Dossards
order by place desc, Dossards asc


Voilà, merci pour la réponse.
petit-ourson
Pas simple, c'est discutable. C'est une procédure stockée avec tous les avantages et inconvénients qu'une procédure stockée apporte. ;o)
Didier M
Je viens de chercher et peux être trouvé !
Mais je ne sais pas comment écrire la requète, donc voilà ci-dessous la chose !

CODE
mysql> SET _AT_num := 0, _AT_rank := 0, _AT_prev := NULL;
mysql> SELECT _AT_num := _AT_num + 1 AS row,
_AT_rank := if(@prev != php, _AT_num, _AT_rank) AS rank,
country, _AT_prev := php AS php
FROM statsPHP ORDER BY php;
+------+------+---------------+-----+
| row | rank | country | php |
+------+------+---------------+-----+
| 1 | 1| Polynésie Fr.    | 67 |
| 2 | 2| Turk & Caicos   | 55 |
| 3| 3| France              | 41 |
| 4| 4| USA                 | 31 |
| 5| 4| Canada            | 31 |
| 6| 6| Groënland        | 17 |
| 7| 6| Israel               | 17 |
+------+------+---------------+-----+


Merci pour votre aide.
Kioob
euh... j'insiste, mais qu'est ce qui te gène dans cette requête ?
CODE
select Dossards, 1+count(b.Total_points) as place
from danseur_$Saison a
    left join danseur_$Saison b on a.Total_points < b.Total_points
group by a.Dossards
order by place desc, Dossards asc


Didier M
Donc je viens de réessayer la requète de Kioob et mysql me répond :

Erreur SQL 1!
Column 'Dossards' in field list is ambiguous


Donc ?

Merci pour votre réponse.
pluriels
Si je ne me trompe pas, Kioob te donne des indices, pas la réponse à copier / coller.

CITATION
La colonne Dossards dans la liste des champs est ambigüe.

1 - où se trouve la liste des champs dans la requête ?
2 - pourquoi Dossards est ambigu ?


Kioob
La colonne est ambigu car la table est utilisée deux fois. Le "group by" étant fait sur a.Dossards, c'est donc a.Dossards que tu dois sélectionner.
Et met un "order by" ascendant, sinon tu risques de ne pas comprendre tongue.gif
pluriels
disons que je voulais ajouter quelques indices, mais maintenant il suffit de continuer la réflexion.

CODE
select a.Dossards, 1+count(b.Total_points) as place
from danseur_$Saison a
    left join danseur_$Saison b on a.Total_points < b.Total_points
group by a.Dossards
order by place desc, a.Dossards asc
Didier M
Donc, je viens de faire un nouvel essais comme ceci :

CODE
select *, 1+count(b.Total_points) as place
from danseur_$Saison a
    left join danseur_$Saison b on a.Total_points < b.Total_points
group by a.Dossards
order by place asc


Et là cela fonctionne !

Maintenant j'aie une clause where à ajouter et là cela ce complique de nouveau !!!

la clause est :

CODE
WHERE Catégorie  ='Cadet 3' AND valid  <>'x'


En effet je doit faire le tri part catégorie et voir si le couple est OK (valid).

Merci encore



pluriels
tu as tous les éléments à l'écran ...
Par contre je te conseille d'apprendre à utiliser les alias de tables dans les requêtes.

Ceci est une version "bas débit" de notre forum. Pour voir la version complète avec plus d'information, la mise en page et les images, veuillez cliquer ici.