选择最多两列(重新访问)

时间:2010-02-27 20:38:59

标签: sql mysql

我问了一个类似的问题before后才发现我认为答案没有用,因为我没有问正确的问题(并没有注意到回答者告诉我这个) 。重新审视,我有一个比较表。我正在尝试为每组两名学生选择具有最大版本的行。所以我一直在做的事情:

SELECT subID1, subID2, stu1,stu2,comparisonID,MAX(stu1vers+stu2vers) AS maxvers 
FROM comparisons
WHERE assignmentID=9 AND stu1!=stu2 
GROUP BY stu1,stu2;
+--------+--------+------+------+--------------+---------+
| subID1 | subID2 | stu1 | stu2 | comparisonID | maxvers |
+--------+--------+------+------+--------------+---------+
|     15 |     11 |    1 |    6 |           64 |       6 |
|     11 |      3 |    6 |    1 |           55 |       5 |
+--------+--------+------+------+--------------+---------+

不起作用,因为我只需要maxvers为6的行。我上次得到的答案是:

SELECT subID1,subID2,stu1,stu2, comparisonID 
FROM comparisons WHERE stu1Vers + stu2Vers = (
    SELECT MAX(stu1Vers+stu2Vers) 
    FROM comparisons 
    WHERE stu1 != stu2 AND assignmentid=9
) AND stu1!=stu2 AND assignmentid=9 
GROUP BY stu1,stu2;

我真的认为这样做 - 只是发现这个查询表中针对该分配的最大版本,然后查找与该最大版本匹配的行。但这并不好,因为两个学生的版本号可能较低:

+--------+--------+------+------+--------------+---------+
| subID1 | subID2 | stu1 | stu2 | comparisonID | maxvers |
+--------+--------+------+------+--------------+---------+
|     44 |     23 |   37 |   36 |          153 |       2 |
|     44 |     36 |   37 |   39 |          156 |       3 |
|     44 |     34 |   37 |   40 |          154 |       3 |
|     36 |     23 |   39 |   36 |           95 |       3 |
|     36 |     34 |   39 |   40 |           96 |       4 |
...
+--------+--------+------+------+--------------+---------+

我需要选择所有这些记录,因为stu1和stu2的每个组合都是唯一的。我如何为stu1,stu2的每个组合的max(sub1vers + sub2vers)行(即,在那里的第一个表中,我仍然需要比较ID 64)。

3 个答案:

答案 0 :(得分:2)

编辑特定于MySQL的查询会产生非聚合列的错误值。请改用便携式查询。

假设您在MySQL下运行(基于您的问题标签以及原始SQL查询),那么您可以发出以下声明: < / p> <击>

SELECT subID1, subID2,stu1,stu2,comparisonID,MAX(stu1vers+stu2vers) AS maxvers
 FROM comparisons
 WHERE assignmentID=9 AND stu1!=stu2
 GROUP BY LEAST(stu1,stu2), GREATEST(stu1,stu2);

<击>

如果您需要更好的可移植性(也可以在例如Postgres上发出查询),则需要稍微复杂一点的查询,此处使用单个JOIN

SELECT c1.subID1, c1.subID2,c1.stu1,c1.stu2,c1.comparisonID,c2.versmax
 FROM comparisons AS c1
 INNER JOIN (
  SELECT
    LEAST(stu1,stu2) AS stuA,
    GREATEST(stu1,stu2) AS stuB,
    MAX(stu1vers+stu2vers) AS versmax
   FROM comparisons
   WHERE assignmentID=9 AND stu1<>stu2
   GROUP BY stuA, stuB
 ) AS c2
 ON ((c1.stu1=c2.stuA AND c1.stu2=c2.stuB) OR
     (c1.stu2=c2.stuA AND c1.stu1=c2.stuB)
    ) AND c1.stu1vers+c1.stu2vers=c2.versmax
 WHERE c1.assignmentID=9 AND c1.stu1<>c1.stu2;

请注意,如果两个组合产生相同的maxvers,那么对于一对唯一的学生来说,更便携的查询可能仍会返回两个行(除非您决定提供区分二),例如:

+--------+--------+------+------+--------------+---------+ 
| subID1 | subID2 | stu1 | stu2 | comparisonID | maxvers | 
+--------+--------+------+------+--------------+---------+ 
|     15 |     11 |    1 |    6 |           64 |       6 | 
|     11 |      3 |    6 |    1 |           55 |       6 | 
+--------+--------+------+------+--------------+---------+ 

答案 1 :(得分:1)

SELECT subID1, subID2, stu1,stu2,comparisonID,MAX(stu1vers+stu2vers) AS maxvers
FROM comparisons
WHERE assignmentID=9 AND stu1!=stu2
GROUP BY stu1,stu2

ORDER BY MAX(stu1vers+stu2vers) DESC
LIMIT 1

或者我错了?

答案 2 :(得分:1)

很抱歉,您上次询问时我没有正确理解您的问题。怎么样:

SELECT
    subID1,
    subID2,
    T3.stu1,
    T3.stu2,
    comparisonID,
    stu1vers + stu2vers AS maxvers
FROM (
    SELECT assignmentId, stu1, stu2, MAX(vers) AS maxvers
    FROM (
        SELECT
            assignmentId,
            stu1vers + stu2vers AS vers,
            LEAST(stu1, stu2) AS stu1,
            GREATEST(stu1, stu2) AS stu2
        FROM comparisons
        WHERE stu1 <> stu2) AS T1
    GROUP BY assignmentId, stu1, stu2
) AS T2
JOIN comparisons AS T3
    ON T2.stu1 = LEAST(T3.stu1, T3.stu2)
    AND T2.stu2 = GREATEST(T3.stu1, T3.stu2)
    AND T2.maxvers = T3.stu1vers + T3.stu2vers
    AND T2.assignmentId = T3.assignmentId
WHERE T3.assignmentId = 9

这个按stu1和stu2分组来查找最大版本,使用比较表进行自联接以获取相应行的剩余列。假设stu1和stu2的顺序无关紧要。