Forum Clubic

SQL Meilleur score d'un joueur sur UltraStar

Bonjour à tous,

Voilà j’ai un petit problème sur une requete SQL que je n’arrive pas à faire.
En fait je souhaite faire un programme qui permette d’exporter les scores du jeu “Ultrastar” (clone gratuit de singstar) vers une page web.

Mon idée serait qu’après avoir joué, on lance le programme qui irait chercher les scores dans le fichier ultrastar.db. (base au format sqllite) et qui remplirait une base mysql placé sur un compte chez free. Ceci afin de pouvoir faire un tableau de scores commun avec nos amis.

La base est composée de 2 tables :
US_Scores
-> SongID
-> difficulty
-> Player
-> Score

US_Songs
-> ID
-> Artiste
-> Title
-> Play (je crois mais ce champs, je m’en fout en fait : il comptabilise le nombre de fois qu’une chanson a été jouée).

Ce que je voudrais c’est extraire de la base la liste des meilleurs scores par chanson et par joueur, pour obtenir une seule ligne, par exemple :
artiste, titre, difficulty, player, score
Nirvana, Rape me, 0, toto, 5000
Nirvana, Rape me, 0, titi, 4500
Queen, Show must go on 0, toto, 3000
Etc…

Donc le meilleur score pour chaque joueur, sur chaque chanson et pour chaque difficulté.

J’ai essayé :
SELECT artiste, title, difficulty, player, score FROM us_songs, us_scores w WHERE us_songs.id=us_scores.songid GROUP BY player, score

Mais en fait ça me donne la liste complète (j’ai tous les scores pour un joueur sur une même chanson pour une même difficulté : or il me faut uniquement son meilleur score). Je pense qu’il faut faire une requête imbriquée, mais je n’arrive pas à la construire.

Quelqu’un a-t-il une idée, je pense que ce ne doit pas être très dur, mais je sèches (mes cours d’SQL sont beaucoup trop anciens).

(je précise qu’il s’agit du ‘mod’ ultrastar deluxe : dans la version normale les scores ne sont pas stockés dans une base de donnée).

Merci de votre aide :slight_smile: par avance.

EDIT :
****************************************** SOLUTION ******************************************

SELECT us_scores.player, us_songs.artiste, us_songs.title, us_scores.difficulty, Max(us_scores.score) AS MaxDescore
FROM us_songs INNER JOIN us_scores ON us_songs.id = us_scores.songid
GROUP BY us_scores.player, us_songs.artiste, us_songs.title, us_scores.difficulty;

Edité le 08/07/2008 à 15:56

SELECT s.artiste, s.title, w.difficulty, w.player, max(w.score) FROM us_songs s, us_scores w WHERE s.id=w.songid GROUP BY s.player

Je pense que ca, ca doit le faire. Par contre tu auras le meilleur score, peu import la difficulté.
Edité le 08/07/2008 à 10:50

Salut et merci de ton aide, je viens d’essayer sous access, et ça me donne une erreur :
Le problème c’est que la clé primaire de us_scores, c’est forcément la ligne complète à savoir “songid,difficulty,player,score”.
Donc pas possible de faire un agrégat uniquement sur “songid” par exemple, il faut obligatoirement le faire sur tous les champs.

Ca vient des limites d’access ? ça marchera sur du sql lite ?

C’est quoi l’erreur exactement ?

Ben en fait si je met ta requête telle quelle, ça donne :
Vous avez essayé d’exécuter une requête ne comprenant pas l’expression spécifiée ‘artiste’ comme une partie de la fonction d’agrégat.
(agrégat = regroupement).

Je me dit que je vais essayer en ajoutant une clé primaire à ma base pour éviter d’avoir à faire une clé sur la collusion des 4 champs.

Bon en fait, j’avais fait une erreur dans ma bdd access, j’avais pas vérifié la cohérence des types de donnée entre us_scores.songid et us_songs.id… (un texte et l’autre numérique) désolé…

Donc, j’ai finalement réussi je pense en mettant ça :
SELECT us_scores.difficulty, us_scores.player, Max(us_scores.score) AS MaxDescore, us_songs.id, us_songs.artiste, us_songs.title
FROM us_scores, us_songs
GROUP BY us_scores.songid, us_scores.difficulty, us_scores.player, us_songs.id, us_songs.artiste, us_songs.title
HAVING us_songs.id=us_scores!songid;

Ce qui est très proche de ta requête initiale (sauf le having). Qu’en penses tu ? Ca te sembles correct ? sur ma base avec très peu d’échantillon ça marche (j’ai pas encore testé avec des niveaux de ‘difficulty’ différents).

Edit : Après test, il semblerait que ça marche aussi pour la ‘difficulty’ j’ai bien une ligne avec un autre score pour une ‘difficulty’ différente.
Edité le 08/07/2008 à 11:49

Ya des truc superflux, comme grouper avec us_scores.songid et us_songs.id en même temp., et meme le fait de groupé le player et l’id ca revien au meme aussi (enfin group pas l’id comme ca si ya plusieur player avec le meme nom ).

Sinon si ca fait ce que tu veux, c’est le principal :smiley:
Edité le 08/07/2008 à 11:50

Salut, oui c’est probable pour le superflux, vu que c’est construit via le requeteur d’access… :wink:
Mais il m’obligeait à faire ces regroupement sinon marchait pas…pour les songid et song.id effectivement : je vois pas l’intérêt !

pour le joueur, impossible d’y en avoir deux avec strictement le même nom : on pourrait pas les différencier, mais le champs player fait 150 caractères donc y’a de quoi mettre un signe distinctif.

En tout cas merci pour ton coup de main qui a débloqué ma situation.

Bon en fait, un dernier post, pour donner LA VRAI solution (du moins une plus belle que celle que j’ai mis avant) :
[b]

SELECT us_scores.player, us_songs.artiste, us_songs.title, us_scores.difficulty, Max(us_scores.score) AS MaxDescore
FROM us_songs INNER JOIN us_scores ON us_songs.id = us_scores.songid
GROUP BY us_scores.player, us_songs.artiste, us_songs.title, us_scores.difficulty;

[/b]

Trouvée grâce à anapajari sur H.FR (hum hum…:whistle:)
Edité le 08/07/2008 à 15:55