2013-11-09 5 views
0

У меня есть таблица с этой структурой:Рейтинг каждой группы строк таблицы

ID NAME RANK 
10 A  1 
11 A  2 
12 A  3 
13 A  4 
14 B  1 
15 B  2 

Эта таблица огромен и около 500 строк, вставленный в него каждую минуту. Для поддержания заказа для каждой группы, по имени, мы используем, прежде чем триггер вставки, как следующее:

begin 

    SELECT NVL(MAX(RANK+1),1) INTO RANK FROM tablename 
    WHERE NAME=:NEW.NAME; 

end; 

Это работает хорошо, но иногда возвращает неверные значения, например, (14,8,11,4,5) вместо (1,2,3,4,5). Мы исследовали наш код, поэтому мы не обновили этот столбец.

В чем может быть проблема? Если этот метод ранжирования неверен, то какой метод лучше всего это сделать?

+0

Для получения более высоких значений, чем ожидалось, странно. Если бы это были более низкие значения, я бы сказал, это из-за параллельной записи, так что несколько вложений обнаруживают одно и то же максимальное значение. Извините, я понятия не имею, что случилось. Тем не менее, вам действительно нужны ряды с приращениями одного? Обычно вы просто используете последовательность, получая, например, A/1, A/2, B/3, A/4. Ранги для A будут 1,2,4, которые не являются приращениями одного, но все еще упорядочены. Разве этого не хватит? –

+0

Мы не можем использовать этот метод для ранжирования, потому что мы используем этот столбец при других вычислениях и его нужно упорядочить для каждой группы. – Radi

+0

Является ли (select max), когда у нас слишком много параллельных вставок, возвращают неверные результаты? – Radi

ответ

1

Как указано в моем комментарии, я не вижу причины, чтобы значения были выше ожидаемого. Поэтому я не могу ответить на ваш первоначальный вопрос.

Тем не менее, я предлагаю вам вместо этого использовать последовательность, также упомянутую в моих комментариях выше. Гарантируется, что последовательность будет работать с одновременным доступом, а ваш подход - нет. Чтобы наконец-то последовательных значений, можно использовать агрегатную функцию для этого:

select name, row_number() over (partition by name order by seq_no) as rank_no 
from tablename; 

Вы можете создать вид, скрывая seq_no и показывая только rank_no. Таким образом, ваш клиент получает то, что хочет видеть.

+0

Я думаю, что вы почти там ... нет причин для отдельной последовательности; вы можете просто использовать столбец идентификатора, который выглядит так, как будто он заполнен последовательностью. Затем вы можете полностью удалить столбец «RANK». – Ben

+0

Спасибо, Бен, но я не могу использовать столбец ID вместо Ранга, потому что в некоторых случаях пользователям нужно переопределить строки, а затем столбцы рангов будут обновлены для группы. – Radi

+0

выберите имя, row_number() over (раздел по порядку имени по id) в качестве rank_no из ## abc; Я думаю, что это немного правильно с небольшой коррекцией. –

Смежные вопросы