2009-07-16 13 views
21

Tengo una tabla que tiene algunas columnas: Usuario, Categoría, Valorconsultas de SQL Server para el Ranking (RowNumber) y Agrupaciones

Y quiero hacer una consulta que me dará un ranking, de todos los usuarios el valor, pero restablecer para la categoría.

Ejemplo:

user1 CategoryA 10 
user2 CategoryA 11 
user3 CategoryA 9 
user4 CategoryB 3 
user1 CategoryB 11 

la consulta devolvería:

Rank User Category 
1  user2 CategoryA 
2  user1 CategoryA 
3  user3 CategoryA 
1  user1 CategoryB 
2  user4 CategoryB 

¿Alguna idea?

Escribo la consulta y especifico la Categoría, funciona pero luego tengo que escribir loops y es muy lenta.

+0

Mi consulta actual: SELECT Rango() sobre (Ordenar por Valor, usuario, Categoría) como filas, categoría, usuario de la Tabla1 Grupo por usuario, Categoría, valor de la orden por rangos asc – bladefist

Respuesta

43

uso "de reparto por" en la función de clasificación OVER clause

SELECT 
    Rank() over (Partition by Category Order by Value, User, Category) as ranks, 
    Category, User 
FROM 
    Table1 
Group By 
    User, Category, Value 
Order by 
    ranks asc 
+0

1,261,473 registros en 33 segundos (con una combinación de tabla agregué que no estaba incluido en la pregunta). Gracias – bladefist

+0

Para obtener el mismo orden de salida que muestra la salida de la pregunta, Ordenar por categoría, Rangos. Además, el usuario devuelve el usuario de base de datos (es decir, dbo) y debe citarse para llegar a la columna llamada Usuario. (Citado ya sea [usuario] o con el identificador entre comillas en "usuario"). –

+0

@Shannon: Comencé con la consulta que OP agregó en un comentario. Solo quería mostrar la partición por – gbn

3
Select User, Category, 
    (Select Count(*) From Table 
     Where Category = A.Category 
     And Value <= A.Value) Rank 
From Table A 
Order By Category, Value 

si el valor puede tener duplicados, a continuación, usted debe decidir si quiere 'contar' los incautos (equivilent a RANK) o no (equivilent a DENSE_RANK, dar gracias @shannon)

Rango ordinario:

Select User, Category, 
    (Select 1 + Count(*) From Table -- "1 +" gives 1-based rank, 
     Where Category = A.Category -- take it out to get 0-based rank 
     And Value < A.Value) Rank 
From Table A 
Order By Category, Value 

"denso" Rango:

Select User, Category, 
    (Select 1 + Count(Distinct Value) -- "1 +" gives 1-based rank, 
     From Table      -- take it out to get 0-based rank 
     Where Category = A.Category  
     And Value < A.Value) Rank 
From Table A 
Order By Category, Value 
+0

muy ineficiente. El hecho de que esté usando RANK implica al menos SQL 2005. – gbn

+0

Es cierto. SQL 2008. Probaré todas las respuestas – bladefist

+0

Pero a) la claridad es lo primero, luego la eficiencia ... yb) el problema es sobre los usuarios, por lo que no estamos hablando de miles de millones de registros ... –

Cuestiones relacionadas