2010-06-21 2 views
4

У меня есть база данных, полная спортивных результатов. Я хотел бы выбрать некоторые результаты, основанные на некоторых характеристиках предыдущих результатов. Вот структура базы данных:Как выбрать строки на основе значений в других строках

CREATE TABLE `results` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , 
    `date` DATETIME NOT NULL , 
    `home_score` INT NOT NULL , 
    `away_score` INT NOT NULL , 
    `home_team_id` INT NOT NULL , 
    `away_team_id` INT NOT NULL 
); 

Так что я хотел бы сделать запросы, как «найти результаты, когда команда выиграла две свои предыдущие домашние игры» - то есть для определенного порядка home_team_id по по дате, а затем выберите каждую строку где в предыдущих двух строках home_score> away_score.

Я знаю, что это немного сложно, поэтому любые указатели на то, как решить эту проблему, будут оценены по весу. В настоящее время у меня есть версия на PHP (выбирает все строки, а затем выполняет этот тип запроса), но производительность очень медленная, и она использует огромный объем памяти (в базе данных содержится более 20 000 строк).

EDIT: Спасибо за пару аккуратных ответов. В идеале, однако, я хотел бы иметь возможность запускать запросы по всем столбцам, а не просто смотреть на W, D или L. Более сложным примером будет «найти все результаты, когда домашняя команда выиграла каждый из своих пяти предыдущих домов игры, по крайней мере, за два мяча, а команда гостей потеряла каждую из своих выездных игр хотя бы по одной цели ».

ответ

2

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

SELECT * FROM 
    (SELECT * FROM results WHERE home_team_id = ID ORDER BY date DESC LIMIT 1) r1 
    INNER JOIN results r2 ON r2.id = r1.prev_result_id 
    WHERE r1.home_score > r1.away_score AND r2.home_score > r2.away_score 

EDIT. Чтобы улучшить это, вы также можете указать поле next_result_id (оно проиндексировано) и иметь его NULL для последнего результата (так как пока нет следующего результата). Таким образом, вы можете избавиться от суб-запроса в FROM, так как вам не придется заказывать по дате на всех:

SELECT * FROM results r1 INNER JOIN results r2 ON r2.id = r1.prev_result_id 
WHERE r1.home_team_id = ID AND r1.next_result_id IS NULL 
AND r1.home_score > r1.away_score AND r2.home_score > r2.away_score 

Это особенно хороший способ, если вы хотите найти все команды, которые выиграли их предыдущие совпадения, потому что теперь вы можете просто опустить r1.home_team_id = ID из предложения where, и он должен дать вам одну строку за каждую команду, выигравшую свои предыдущие два матча.

2

В зависимости от полного спектра запросов, которые вам нужны, я могу рассмотреть вопрос о денормализации. , например. в таблице команды добавить столбцы, такие как

home_performance = 'WWDLWW' 
away_performance = 'WWLLWL' 
overall_performance = 'WWWWDLLLWWWL' 

Затем AdHoc запросы, такие как выиграли их последние 2 домашние игры можно ответить, делая

home_performance LIKE '%WW' 

Или выиграл 4 подряд будет overall_performance LIKE '%WWWW%'

Эти производные столбцы могут быть заполнены с помощью GROUP_CONCAT