Forum Webscript.Ru
Общие => Базы данных => Тема начата: shred от 04 Октября 2003, 19:39:58
-
Имеем: таблица с участниками (id, nick) и таблица с результатами заездов этих участников (id, nick_id, time, action_date, где time - за какое время доехал, action_date - дата, когда это было).
Требуется: что-то вроде "Топ 10 ездаков", со строками вида "time | nick | action_date", nick\'и, конечно, повторяться не должны, сортировка по time, меньшее впереди.
Если пишем
select * from участниками у, результаты р
where у.id=р.nick_id
group by у.id
избавляемся от повторов ников, но и теряем нужную запись (с лучшим временем), вместо нее - произвольная.
Если писать group by р.time asc, у.id вылазят записи о всех заездах. В сущности, все ок, только не знаю как повторяющиеся ники убрать.
Вот если бы можно было сначала отсортировать, а потом с помощью group by у.id отстрелить дубли :) Но порядок group by, order by и т.д. строго определен...
Как быть?
-
Попробуй вставить ключевое слово DISTINCT
-
сначала написал а потом только подумал.
прошу прощения.
-
если запраршивать min(time), то время не пропадет.
-
если запраршивать min(time), то время не пропадет.
Я так и делаю :) НО! Если при этом выводить и дату, то она не соответствует нику и результату заезда (ник, как ни странно, соответствует результату).
Попробуй вставить ключевое слово DISTINCT
Пробовал, эффекта не добился. Может как-то не так пробовал, но вариант, вроде всего один.
ЗЫ. mysql v4.0.15
-
И вообще, group by ведет себя не совсем однозначно. Если писать group by поле - отстреливает дубликаты, если group by поле, поле, поле наворочено и удобно сортирует. Полагаю так и должно быть :)
-
> Если при этом выводить и дату, то она не соответствует нику и результату заезда (ник, как ни странно, соответствует результату)
оно берет первое попавшееся значение для каждого y.id.
Одним запросом не сделаешь. Сначала выбираешь все значения id и минимального, а потом соответсвующие этим значениям остальные данные.
-
Интересно, а не в mysql\'e это можно было бы сделать одним запросом? (скажем в pgSQL)
-
Все зависит от того как в других СУБД реализована выборка при GROUP BY, т.е возвращаются ли там данные соответствующие минимальному значению или нет. Этот момент в стандарте SQL не описан, потому каждая СУБД реализует так как ей удобно.
Даже в том-же MySQL начиная с версии 4.1 это можно одним запросом реализовать, но не раньше.
-
В принципе, можно и одним запросом, поскольку проблема только в уникальности участников.
То есть, сделать примитивнийший запрос, который выбирает заезды сортируя по времени, и джойня имя игрока. Естественно, без лимита, или с запасом - скажем, 100.
И выводить, запоминая тех, кто уже был.
Криво, но зато просто :-)
-
select y.nick, y.id, MAX(p.time), p.action_date
from участниками у INNER JOIN результаты р ON у.id=р.nick_id
group by у.id, p.action_date DESC
LIMIT 10
-
Alexandr:
"INNER JOIN and , (comma) are semantically equivalent. Both do a full join between the tables used."
Эт тоже самое, что и from участниками у, результаты р where у.id=р.nick_id. На всякий случай я попробовал - не то.
-
shred:
Эт тоже самое, что и
ага
shred:
На всякий случай я попробовал - не то.
Что не то?
Выборка не та? Тогда я не понял что тебе вообще надо...
Объясни толково.
-
Поясняю: надо среди результатов каждого участника найти лучший и представить лучшие результаты участников в табличке, самые лучшие результаты - вверху; поля: результат (время), ник, дата (когда это свершилось). Одним запросом. В mysql\'e.
-
Думаю сработало бы, что-нить вроде этого:
select р.time, у.nick, р.action_date from участниками у, результаты р
where у.id=р.nick_id and у.id = (
select distinct р.nick_id
from результаты р
order by р.time)
Но подзапросов в mysql\'e пока нет :(
-
Шред, тебе нужен топ.
Всего 11 примитивных запросов.
Не парься по этому поводу.
Замерь время создания этого топа и забудь :-)
-
shred:
надо среди результатов каждого участника найти лучший и представить лучшие результаты участников
А мой-то запрос тебе чего не нравится?
select y.nick, y.id, MIN(p.time), p.action_date
from участниками у INNER JOIN результаты р ON у.id=р.nick_id
group by у.id, p.action_date DESC
ORDER BY 3
Я кстати в первый раз перепутал MIN c MAX\'ом....
Этот запрос выберет минимальное время для каждого участника
и выдаст его ид\'шник, ник, это самое время и наиболее позднюю дату когда это свершилось, если у него 2 одинаковых времени (если уберёшь DESC, то наиболее раннюю)
и отсортирует всю выборку по 3 полю, т.е. по мин. вр. для каждого участнику, в порядке убывания.
Если добавишь в конец LIMIT 10, то выдаст тока 10 первых
-
Оно не отстреливает дубликаты ников, т.е. если у кого-то 5 результатов заездов, они все 5 тут и будут.
-
shred:
Оно не отстреливает дубликаты ников
Ты что-то путаешь....
Поторяю
Alexandr:
Этот запрос выберет минимальное время для каждого участника
-
ну и каков результат? придумали что-нить?
такая же проблема.. ищу не нашел пока решения.
-
кекс
давай струтуру таблицы, версию MySQL.
-
Искал такую же тему... нифига ненашел..
как то вы сложно пишете.. а не проще так
SELECT id, user, min(bestlap) as bestlap, min(totalrace) as totalrace, times FROM table GROUP by user ORDER BY $sort LIMIT 100
сорт это или bestlap или totalrace, если надо вывести по лучшему результату например круга или общего времени...
я так сделал все вроде работает на первый взгляд. пойду смотреть, совпадает ли время лучшего круга с временем общим:)
хотя это и не очень важно.. нужны лучшие врмена..
-
кекс
Romik Chef - на первой странице об этом писал.
-
for_i_0
что-то я там не видел:(