- Поисковые системы
- Практика оптимизации
- Трафик для сайтов
- Монетизация сайтов
- Сайтостроение
- Социальный Маркетинг
- Общение профессионалов
- Биржа и продажа
- Финансовые объявления
- Работа на постоянной основе
- Сайты - покупка, продажа
- Соцсети: страницы, группы, приложения
- Сайты без доменов
- Трафик, тизерная и баннерная реклама
- Продажа, оценка, регистрация доменов
- Ссылки - обмен, покупка, продажа
- Программы и скрипты
- Размещение статей
- Инфопродукты
- Прочие цифровые товары
- Работа и услуги для вебмастера
- Оптимизация, продвижение и аудит
- Ведение рекламных кампаний
- Услуги в области SMM
- Программирование
- Администрирование серверов и сайтов
- Прокси, ВПН, анонимайзеры, IP
- Платное обучение, вебинары
- Регистрация в каталогах
- Копирайтинг, переводы
- Дизайн
- Usability: консультации и аудит
- Изготовление сайтов
- Наполнение сайтов
- Прочие услуги
- Не про работу
Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий
Ребята помогите пожалуйста с алгоритмом, уже вторые сутки лоб морщу, но эффективного алгоритма придумать не могу.
Исходные данные.
есть таблица с играми футбола
match
`id` int(11) счетчик
projectteam1_id int(11) Это код команды №1
projectteam2_id int(11) Это код команды №2
match_date datetime дата игры
и таблица с дисквалификациями игроков
match_discv
`id` int(11) счетчик
`match_id` int(11) id матча где был дисквалифицирован игрок
`projectteam_id` int(11) id команды где играл игрок
`teamplayer_id` int(11) id игрока
`srok` int(11) срок дисквалификации (количество пропускаемых игр)
Задача сделать выборку игроков имеющих неснятую дисквалификацию на текущее число.
Дисквалификация снимается с игрока после того как его команда сыграет то число матчей на которое он отстранен обычно отстраняют на 1 игру, но бывает что и на 4 игры.
Свой ход мыслей как это решать не озвучиваю, ибо не хочу что бы вы пошли за мной по ложному следу, а посмотрели свежим взглядом.
В общем нужен эффективный алгоритм. В идеале конечно все свести в один сложный запрос mysql, но боюсь это не реально.
Заранее благодарен за помощь
как-то так..
select match_discv.teamplayer_id
from match, match_discv
where match.id > match_discv.match_id
and match_discv.projectteam_id in (match.projectteam1_id,match.projectteam2_id)
group by match_discv.teamplayer_id, match_discv.srok
having count(match.id) < match_discv.srok
---------- Добавлено 18.03.2013 в 17:10 ----------
в группировку match_discv.`id` нужно добавить , чтобы повторные дисквалификации хорошо обрабатывались
---------- Добавлено 18.03.2013 в 17:11 ----------
т.е. так:
select match_discv.teamplayer_id
from match, match_discv
where match.id > match_discv.match_id
and (match_discv.projectteam_id = match.projectteam1_id
or
match_discv.projectteam_id = match.projectteam2_id)
group by match_discv.id, match_discv.teamplayer_id, match_discv.srok,
having count(match.id) < match_discv.srok
---------- Добавлено 18.03.2013 в 17:12 ----------
:) т.е.
так
select match_discv.teamplayer_id
from match, match_discv
where match.id > match_discv.match_id
and match_discv.projectteam_id in (match.projectteam1_id,match.projectteam2_id)
group by match_discv.id, match_discv.teamplayer_id, match_discv.srok
having count(match.id) < match_discv.srok
Гораздо проще будет, если из колонки "srok" после каждого матча вычитать 1.
Смотря какая задача.
Если вычитать, то нельзя будет сказать, что на момент игры год назад игроку оставалось пропустить N матчей.
from match, match_discv
where match.id > match_discv.match_id
and match_discv.projectteam_id in (match.projectteam1_id,match.projectteam2_id)
group by match_discv.id, match_discv.teamplayer_id, match_discv.srok
having count(match.id) < match_discv.srok
Не пойму как в условия включить сегодняшнее число.
Можно конечно ввести доп поле и оттуда вычититать по единичке, пока до нуля не дойдет. Но тут решая эту задачу мы создаем себе другую, не менее сложную.
Ну тогда другой способ, чтобы не насиловать базу данных пятиэтажными запросами с having-ами.
В таблицу match_discv добавляете поля:
date_start
date_finish
srok_rest
Когда в эту таблицу заносится игрок, то в date_start заносится дата дисквалификации, date_finish пустая, srok_left равно srok.
После каждого матча команды из srok_left вычитается 1.
Когда там остаётся 0 (т.е. пропущено нужное количество матчей), в date_finish заносится дата снятия дисквалификации.
Таким образом, для каждой дисквалификации каждого дисквалифицированного игрока появляется дата начала и дата завершения, и поставленная задача (выбрать игроков, имеющих дисквалификацию на произвольную дату) решается.
select match_discv.teamplayer_id
from match, match_discv
where match.id > match_discv.match_id
and match.match_date <= сегодня
and match_discv.projectteam_id in (match.projectteam1_id,match.projectteam2_id)
group by match_discv.id, match_discv.teamplayer_id, match_discv.srok
having count(match.id) < match_discv.srok
всегда 0 строк выбирает, даже когда игроку в последнем матче дисквалификацию ставлю.
Попробуйте такой вариант:
Вместо NOW() лучше использовать конкретную дату, т.к. с NOW() некоторые индексы могут не работать.
Благодарю. запрос рабочий, нужно его хорошо протестировать.
Благодарю всех отписавшихся в этой теме.