2010-06-21 57 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行)。

编辑:感谢几个整洁的答案。不过,理想情况下,我希望能够在所有栏目上进行查询,而不仅仅是看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 

编辑。 为了进一步改善这一点,您还可以使用next_result_id字段(已编制索引),并将最后一个结果的值设为NULL(因为还没有下一个结果)。这样,你可以得到摆脱子查询从,因为你没有按日期在所有订购:

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 

这是特别的好方法,如果你想找到的是赢得了所有球队他们以前的比赛,因为现在你可以简单地从where子句中省略r1.home_team_id = ID,并且它应该为每个赢得他们前两场比赛的球队提供一行。

2

根据您需要的全部查询,我可能会考虑denormalising。 例如在球队表中添加,如

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

然后即席查询,如赢得了他们的最后两个主场比赛列可以通过连续做

home_performance LIKE '%WW' 

还是赢得了4回答是overall_performance LIKE '%WWWW%'

这些派生列可以通过使用GROUP_CONCAT