【问题标题】:How to select rows based on values in other rows如何根据其他行中的值选择行
【发布时间】:2010-06-21 08:23:49
【问题描述】:

我有一个充满运动成绩的数据库。我想根据之前结果的一些特征选择一些结果。这是数据库结构:

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。一个更复杂的示例是“查找主队在前五个主场均获胜的所有结果至少两场比赛,而客队每场客场比赛都输掉至少一球。”

【问题讨论】:

    标签: sql mysql


    【解决方案1】:

    根据您需要的所有查询,我可能会考虑非规范化。 例如在团队表中添加列,例如

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

    然后,诸如赢得最近 2 场主场比赛之类的临时查询可以通过做来回答

    home_performance LIKE '%WW'
    

    或连续赢得 4 次将是overall_performance LIKE '%WWWW%'

    可以使用GROUP_CONCAT 填充这些派生列

    【讨论】:

      【解决方案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(因为还没有下一个结果)。这样您就可以摆脱 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
      

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

      【讨论】:

        猜你喜欢
        • 2021-07-15
        • 2020-12-24
        • 1970-01-01
        • 2018-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-06
        • 1970-01-01
        相关资源
        最近更新 更多