2008-09-18 21 views
6

Tengo una tabla con puntuaciones de juegos, que permite varias filas por ID de cuenta: scores (id, score, accountid). Quiero una lista de los 10 principales identificadores de puntuación y sus puntajes.Obtener una fila por ID de cuenta de la lista

¿Puede proporcionar un enunciado SQL para seleccionar los 10 puntajes principales, pero solo un puntaje por identificación de cuenta?

Gracias!

+0

¿estamos haciendo su tarea? – paulwhit

+4

Tarea o no, la pregunta es buena en mi humilde opinión, ya que un simple DISTINCT no funcionará y es necesario combinarlo con una función de agregación, un problema que también tropecé varias veces, y tener una solución en SO nos beneficiaría a todos. –

Respuesta

2

Primero limite la selección al puntaje más alto para cada identificación de cuenta. Luego tome los primeros diez puntajes.

SELECT TOP 10 AccountId, Score 
FROM Scores s1 
WHERE AccountId NOT IN 
    (SELECT AccountId s2 FROM Scores 
    WHERE s1.AccountId = s2.AccountId and s1.Score > s2.Score) 
ORDER BY Score DESC 
+0

Resulta que esto parece mejor porque selecciona toda la fila. La otra consulta máxima solo se agregó al puntaje máximo en una fila aleatoria para cada cuenta. – Kenzie

+0

fijo: SELECT * partir de las puntuaciones s1 DONDE NO EN accountid (SELECCIONAR accountid partir de las puntuaciones s2 DONDE s1.accountid = s2.accountid y s1.score Kenzie

+2

Sólo me queda tener con esta consulta es que obtengo más de una fila por cada cuenta cuando esa cuenta tiene más de una ocurrencia de su puntaje máximo. Entonces si accoundid 6 tiene puntajes de 50, 75, 40, 75 entonces la consulta devuelve ambas filas con el puntaje de 75. – Kenzie

2

Prueba esto:

select top 10 username, 
       max(score) 
from usertable 
group by username 
order by max(score) desc 
+1

¿Es 'top 10' nuevo? No recuerdo haberlo visto antes? – zigdon

+0

depende del DBMS - era nuevo para SQL Server en 2000 – Danimal

+0

Debería haber especificado mysql. El límite hizo el truco. Gracias. – Kenzie

1

PostgreSQL tiene la DISTINCT ON cláusula, que funciona de esta manera:

SELECT DISTINCT ON (accountid) id, score, accountid 
FROM scoretable 
ORDER BY score DESC 
LIMIT 10; 

no creo que es el estándar SQL, sin embargo, por lo que esperan otras bases de datos para hacerlo diferentemente.

4
select username, max(score) from usertable group by username order by max(score) desc limit 10; 
+0

este necesita un "desc" en el orden por – Magnar

+0

Actualizado, gracias. – zigdon

1
SELECT accountid, MAX(score) as top_score 
FROM Scores 
GROUP BY accountid, 
ORDER BY top_score DESC 
LIMIT 0, 10

Eso debería funcionar bien en MySQL. Es posible que necesite usar 'ORDER BY MAX (puntuación) DESC' en lugar de esa orden por - No tengo mi referencia de SQL a la mano.

0

creo que PostgreSQL (al menos 8,3) requerirá que las expresiones deben coincidir DISTINCT ON iniciales ORDER BY expresiones. ES DECIR. no puede usar DISTINCT ON (accountid) cuando tiene ORDER BY score DESC. Para solucionar este problema, agregarlo a la ORDER BY:

SELECT DISTINCT ON (accountid) * 
FROM scoretable 
ORDER BY accountid, score DESC 
LIMIT 10; 

uso de este método le permite seleccionar todas las columnas de una tabla. Solo devolverá 1 fila por cada cuenta, incluso si hay valores "máximos" duplicados para la puntuación.

Esto fue útil para mí, ya que no estaba encontrando el puntaje máximo (que es fácil de hacer con la función max()) pero en el último tiempo se ingresó un puntaje para un accountid.

Cuestiones relacionadas