2010-04-23 10 views
0

Je veux faire une grille de classement.Afficher une grille de classement pour le jeu: optimisation de la jointure externe gauche et trouver un joueur

J'ai une table avec des valeurs différentes indexées par une clé:

Tableau SimpleValue: varchar clé, valeur int, int playerId

J'ai un joueur qui ont plusieurs SimpleValue.

Tableau joueur: id int, surnom varchar

Imaginez maintenant ces enregistrements:

SimpleValue:

Key  value  playerId 
for  1   1 
int  2   1 
agi  2   1 
lvl  5   1 

for  6   2 
int  3   2 
agi  1   2 
lvl  4   2 

Joueur:

id  nickname 
1  Bob 
2  John 

Je veux afficher un rang de ces joueurs sur divers SimpleValue. Quelque chose comme:

nickname  for  lvl  
Bob   1   5  
John   6   4 

Pour le moment, je générer une requête SQL basée sur quelle touche SimpleValue que vous souhaitez afficher et sur quelle touche SimpleValue vous voulez commander les joueurs.

par exemple: Je veux afficher « lvl » et « pour » de chaque joueur et de les commander sur le « lvl »

La requête générée est:

SELECT p.nickname as nickname, v1.value as lvl, v2.value as for 
FROM Player p 
LEFT OUTER JOIN SimpleValue v1 ON p.id=v1.playerId and v1.key = 'lvl' 
LEFT OUTER JOIN SimpleValue v2 ON p.id=v2.playerId and v2.key = 'for' 
ORDER BY v1.value 

Cette requête fonctionne parfaitement. MAIS si je veux afficher 10 valeurs différentes, il génère 10 'jointure externe gauche'. Existe-t-il un moyen de simplifier cette requête?

J'ai une deuxième question: existe-t-il un moyen d'afficher une partie de ce classement. Imaginez que j'ai 1000 joueurs et que je veux afficher TOP 10, j'utilise le mot-clé LIMIT. Maintenant, je veux afficher le rang du joueur Bob qui est 326/1000 et je veux afficher le joueur de rang 5 ci-dessus et ci-dessous (donc de 321 à 331 position). Comment puis-je y arriver?

merci.

+0

vous gagnez la flexibilité avec vous schéma d'attribut d'entité, mais elle se traduit par l'écriture et l'optimisation des requêtes difficiles. Ces requêtes seraient faciles avec un schéma de table fixe (où les attributs sont juste des colonnes dans une table, et non des lignes). –

Répondre

2

Ceci s'appelle une "requête de tableau croisé". Vous pouvez utiliser des instructions conditionnelles somme comme celui-ci page

Pour:

SELECT p.nickname as nickname 
, SUM(IF(key = "for", value,0)) AS `for` 
, SUM(IF(key = "int", value,0)) AS `int` 
, SUM(IF(key = "agi", value,0)) AS `agi` 
, SUM(IF(key = "lvl", value,0)) AS `lvl` 
FROM Player p 
LEFT OUTER JOIN SimpleValue v1 ON p.id=v1.playerId 
GROUP By p.nickname 
ORDER BY v1.value 
+1

ne voudriez-vous pas ajouter un «GROUP BY» pour rendre les résultats de la requête significatifs? –

+0

Ya, j'ai remarqué ça après l'avoir posté. Merci quand même. – Dan

+0

exactement ce que je veux, merci –