在SQL查询中出现MAX()和`group by`的问题

jrh*_*ath 4 mysql

我正在编写一个特别麻烦的查询.归结为:

我获得了一个结构表:

pid | tid | points
Run Code Online (Sandbox Code Playgroud)

经过一个非常大的查询.

为便于说明:

  • pid =问题ID
  • tid =团队ID
  • points =该团队因该问题而获得的分数.

我想找到为特定pid获得最高分的球队.

我的问题是双重的:

  1. 如果这是一个名字的简单表格,teampoints我怎样才能得到tid每个pid的MAX(点数)?我试过SELECT pid, tid, MAX(points) from teampoints group by pid;但可以理解,那是行不通的

  2. 经过一次相当大的查询,我得到了这个结果.如果我的第一个答案涉及teampoints再次选择数据,有没有办法做到这一点,而无需再次计算整个表?

谢谢

PS:我用的是mysql.


GORY DETAILS:小心谨慎

我的系统中有几个表,它们的相关结构是:

users: uid
teams: tid | eid | teamname
teammembers: tid | uid
events: eid
problems: pid | eid
submissions: subid | pid | uid | eid | points | subts
Run Code Online (Sandbox Code Playgroud)

一些注意事项: - 问题属于事件 - 用户属于团队 - 提交属于问题(pid)和用户(uid).提交表有一个冗余的eid字段,它总是可以从pid中确定.

用例是:

  • 用户组成团队.用户由uid团队识别tid.团队成员存储在teammembers表中.
  • 用户可以提交提交,这些提交存储在提交表中.提交被授予积分.subts是提交提交时的unix时间戳.
  • 用户可以针对同一问题多次提交.计算最新提交的内容(最大子文件).

现在,在这个设置中,我想找到任何给定事件(eid)teamname得分最高的那个points.

我希望这能使我的情况变得清晰.我只想问我需要知道什么.我在评论中提出了这些细节.

编辑:生成teampoints表的查询是:

SELECT s.pid, teamlatest.tid, s.points 
  FROM  submissions s, teammembers tm, teams t, 
      (SELECT max(maxts) AS maxts, pid, tid 
         FROM (SELECT latest.maxts, latest.pid, t.tid 
                 FROM submissions s, teams t, teammembers tm,
                     (SELECT max(subts) AS maxts, pid, uid 
                        FROM submissions 
                        WHERE eid=3 AND status='P' 
                        GROUP BY pid, uid
                     ) AS latest
                 WHERE s.uid=latest.uid 
                   AND s.pid=latest.pid 
                   AND s.subts=latest.maxts 
                   AND latest.uid=tm.uid 
                   AND tm.tid=t.tid 
                   AND t.eid=3
              ) AS latestbyteam
         GROUP BY pid, tid) AS teamlatest
  WHERE s.pid=teamlatest.pid 
    AND teamlatest.tid=t.tid 
    AND t.tid=tm.tid 
    AND tm.uid=s.uid 
    AND s.subts=teamlatest.maxts
Run Code Online (Sandbox Code Playgroud)

out*_*tis 5

  1. 单程:

    SELECT pid, tid, points 
      FROM teampoints
      WHERE (pid, points) IN (
          SELECT pid, MAX(points) 
            FROM teampoints GROUP BY pid
      )
    
    Run Code Online (Sandbox Code Playgroud)

    另一个,使用连接:

    SELECT s1.*
        FROM teampoints AS s1
        LEFT JOIN teampoints AS s2
           ON s1.pid = s2.pid
           AND s1.points < s2.points
        WHERE s2.tid IS NULL
    
    Run Code Online (Sandbox Code Playgroud)
  2. 您可以INSERT INTO为复杂查询提供临时表:

    CREATE TEMPORARY TABLE scores (
        pid INT, tid INT, points INT,
        KEY pp (pid, points)
    );
    INSERT INTO scores (pid, tid, points) 
        SELECT <a complex query>
    
    Run Code Online (Sandbox Code Playgroud)

    然后从中选择最佳得分手.