Выбор следующего элемента из отсортированного списка

Bitterman

Новичок
Krishna
Протестил твой запрос, все то же самое - циклит.
Для такого набора
+----+------+
| ID | Rate |
+----+------+
| 3 | 5 |
| 2 | 5 |
| 19 | 4 |
| 17 | 4 |
| 7 | 3 |
| 1 | 3 |
+----+------+

запрос
[sql]
SELECT MIN(ID) FROM TestImage
WHERE ID <> 19 GROUP BY Rate HAVING Rate >= 4
ORDER BY Rate ASC LIMIT 1
[/sql]
(то есть, когда текущий элемент - 19), возвращает элемент 17, а запрос
[sql]
SELECT MIN(ID) FROM TestImage
WHERE ID <> 17 GROUP BY Rate HAVING Rate >= 4
ORDER BY Rate ASC LIMIT 1
[/sql]
возвращает элемент 19.
Тем не менее, мысль ты мне подкинул, спасибо :)
Думаю, что сделаю так:
сначала запросом
[sql]
select * from TestImage WHERE Rate=$Rate AND ID<$ID ORDER BY Rate DESC, ID DESC LIMIT 1
[/sql]
вычислю следующий элемент с тем же рейтингом, если вернется пустой результат, то тогда использую запрос
[sql]
select * from TestImage WHERE Rate<$Rate ORDER BY Rate DESC, ID DESC LIMIT 1
[/sql]
Вроде получается не очень сложно и работает. Хотя, конечно, надо будет еще потестить.
 

Krishna

Продался Java
Bitterman
А пришли мне плиз полный дамп структуры и данных своей тестовой таблички, а то лень самому делать)

А первый запрос тоже не работает? :)

-~{}~ 06.11.07 13:12:

Так, сгенерил тестовую таблицу на 100.000 строк :))
Так что, заодно и вопрос производительности можно будет разрешить.
Кстати, в поле rate какие значения предполагаются?
Это сумма баллов голосов, или таки средний балл?

-~{}~ 06.11.07 13:14:

Вечером вернусь к вопросу)
Уверен, что вопрос следующей картинки можно порулить одним запросом, с приемлимым уровнем производительности :)
 

Bitterman

Новичок
Krishna
дамп
[sql]
DROP TABLE TestImage;
CREATE TABLE TestImage(
ID int(11) not null default 0,
Rate int(11) not null default 0,
PRIMARY KEY (ID)
);
INSERT INTO TestImage(ID, Rate) VALUES(1, 3);
INSERT INTO TestImage(ID, Rate) VALUES(2, 5);
INSERT INTO TestImage(ID, Rate) VALUES(3, 5);
INSERT INTO TestImage(ID, Rate) VALUES(7, 3);
INSERT INTO TestImage(ID, Rate) VALUES(17, 4);
INSERT INTO TestImage(ID, Rate) VALUES(19, 4);
[/sql]
Первый запрос посмотрел, он делает то же самое, что и мой запрос
[sql]
SELECT *
FROM TestImage
WHERE Rate = $Rate AND ID < $ID
ORDER BY Rate DESC , ID DESC
LIMIT 1
[/sql]
но, по-моему, это скорее ошибка, чем изначально так подразумевалось :)

Gas
Насчет добавить поле Rate и повесить на него индекс - похоже так и придется поступить.

Krishna
Кстати, в поле rate какие значения предполагаются?
Это сумма баллов голосов, или таки средний балл?
Вообще в реальной таблице есть сумма баллов и общее число голосов, но я подумываю о том, чтобы добавить и поле со средним баллом
 

Gas

может по одной?
Bitterman
ну я просто предложил решение в лоб, не факт что оно самое правильное. Krishna вот может вечером лучше предложит ;) (действительно интересно)
 

Krishna

Продался Java
Вот этот вариант рабочий (по-крайней мере для 17 и 19 :) )
[sql]
SELECT t1.id
FROM (

SELECT id,rate
FROM TestImage;
WHERE rate > (
SELECT rate
FROM TestImage;
WHERE id = $current_pic_id ) OR rate = (
SELECT rate
FROM TestImage;
WHERE id = $current_pic_id ) AND id > $current_pic_id
) as t1
ORDER BY t1.rate ASC , id ASC
LIMIT 1
[/sql]

Вопросом производительности займёмся завтра :)

У меня сегодня день рождения, иду отмечать ;)

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

Можно пойти двумя путями - либо завести 3 поля (средний рейтинг, сумма баллов, количество голосов), либо только 2 - средний рейтинг и кол-во голосов, но тогда средний рейтинг нужно хранить с достаточно высокой точностью, иначе, например, если точность 1 порядок после запятой, а кол-во голосов исчисляется в сотнях - несмотря на дополнительные голоса рейтинг меняться не будет из-за потерь на округлении.

Еще нужно прикинуть плотность отдельных значений рейтинга относительно общей массы - для понимания эффективности индексов.
Ну и прогнозируемое количество записей неплохо бы знать :)
 

Bitterman

Новичок
Krishna
У меня сегодня день рождения, иду отмечать
Поздравляю!


Вот этот вариант рабочий
Да, запрос работает, по крайней мере, на тестовом наборе. Но возник вопрос - зачем там вложенный запрос?
Такой запрос
[sql]
SELECT ID, Rate
FROM TestImage
WHERE Rate > $Rate OR Rate = $Rate AND ID > $ID
ORDER BY Rate ASC , ID ASC LIMIT 1
[/sql]
тоже работает "на ура". Я чего-то недопонимаю?
 

Krishna

Продался Java
Bitterman
Ну, я просто торопился :)
Вложенный запрос действительно не нужен, как и подчинённые, если считать, что $Rate нам уже известен.
 

Bitterman

Новичок
Вобщем, спасибо всем, особенно Krishna, запрос заюзал, все работает нормально.
P.S. На самом деле, все как-то просто оказалось, даже немного неловко, что сам не сообразил :)
 
Сверху