2009-07-16 4 views
21

У меня есть таблица, которая имеет несколько столбцов: Пользователь, Категория, стоимостьзапросов SQL Server для ранга (ROWNUMBER) и Группировки

И я хочу, чтобы сделать запрос, который даст мне рейтинг, всех пользователей, значение, но сброс для категории.

Пример:

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

запрос вернет:

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

Есть идеи?

Я пишу запрос и задаю категорию, он работает, но тогда мне приходится писать циклы и очень медленно.

+0

Мой текущий запрос: ВЫБРАТЬ Rank() над (Сортировать по стоимости, пользователь, категория), как ряды, категория, пользователь из Table1 группы по пользователям, Категории, стоимость заказ по рангам возрастанию – bladefist

ответ

43

Использование "раздела по" в функции ранжирования 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 записей за 33 секунд (со счетом join я добавил, что не был включен в вопрос). Спасибо – bladefist

+0

Чтобы получить тот же выходной порядок, что и выходной вопрос, Закажите по категориям, званиям. Кроме того, Пользователь возвращает пользователя БД (т. Е. Dbo) и должен быть указан для доступа к столбцу с именем «Пользователь». (Цитируется либо [пользователь], либо с котируемым идентификатором на «user».) –

+0

@Shannon: Я начал с запроса, который OP добавлен в комментарий. Я только хотел продемонстрировать раздел на – 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 

Если значение может иметь дубликаты, то вы должны решить, хотите ли вы «счетчик» в обманутые (equivilent ранжировать) или нет (equivilent к DENSE_RANK, спасибо @shannon)

Обычный Ранг:

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 

"Густой" Ранг:

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

Очень неэффективно. Тот факт, что он использует RANK, по крайней мере, подразумевает SQL 2005. – gbn

+0

Правда. SQL 2008. Я попробую все ответы – bladefist

+0

Но а) ясность на первом месте, затем эффективность ... и б) проблема в отношении пользователей, поэтому мы не говорим о миллиардах записей ... –