mysql - 从多列中获取两个最大值

时间:2013-05-21 11:17:40

标签: mysql sql

我们可以使用GREATEST从多个列中获取最大价值,如下所示

SELECT GREATEST(mark1,mark2,mark3,mark4,mark5) AS best_mark FROM marks

但现在我希望得到所有(5)分的两个最佳分数。

我可以在mysql查询上执行此操作吗?

表结构(我知道它是错的 - 由某人创建):

student_id  | Name | mark1 | mark2 | mark3 | mark4 | mark5

4 个答案:

答案 0 :(得分:2)

我认为你应该改变你的数据库结构,因为水平地拥有那么多标记(即作为字段/列)已经意味着你做错了。

而是将所有标记放在一个单独的表格中,在该表格中创建多对多关系,然后与SELECT一起执行必要的LIMIT

建议:

  1. 创建一个名为mark_types的表格。列:idmark_type。一世 看你目前有5种商标;这很简单 添加其他类型。
  2. 将您的marks表格更改为3列:idmark / grade / valuemark_type(此列外国限制为 mark_types)。
  3. 在联接和SELECT
  4. 的帮助下编写GROUP BY mark_type查询

答案 1 :(得分:2)

这不是最优雅的解决方案,但如果您无法更改表结构,则可以取消数据,然后应用用户定义的变量来获取每个student_id的行号。代码类似于以下内容:

select student_id, name, col, data
from
(
  SELECT student_id, name, col,
    data,
    @rn:=case when student_id = @prev then @rn else 0 end +1 rn,
    @prev:=student_id
  FROM 
  (
    SELECT student_id, name, col,
      @rn, 
      @prev,
      CASE s.col
        WHEN 'mark1' THEN mark1
        WHEN 'mark2' THEN mark2
        WHEN 'mark3' THEN mark3
        WHEN 'mark4' THEN mark4
        WHEN 'mark5' THEN mark5
      END AS DATA
    FROM marks
    CROSS JOIN 
    (
      SELECT 'mark1' AS col UNION ALL 
      SELECT 'mark2' UNION ALL 
      SELECT 'mark3' UNION ALL 
      SELECT 'mark4' UNION ALL 
      SELECT 'mark5'
    ) s
    cross join (select @rn := 0, @prev:=0) c
  ) s
  order by student_id, data desc
) d
where rn <= 2
order by student_id, data desc;

SQL Fiddle with Demo。这将返回每student_id的前2个标记。内部子查询执行类似于使用UNION ALL进行取消的功能,但是您没有多次查询该表以获得结果。

答案 2 :(得分:0)

您可以创建一个临时表,然后

Create a temporary table in a SELECT statement without a separate CREATE TABLE

查询该表如下

SELECT TOP 2 * FROM temp ORDER BY mark DESC

然后

drop temp table

答案 3 :(得分:0)

好的,这是一个应该与当前表结构一起使用的新答案:

SELECT `student_id`, `Name`, `mark` FROM (SELECT `student_id`, `Name`, `mark1` AS `mark` FROM `marks`
                                          UNION ALL
                                          SELECT `student_id`, `Name`, `mark2` AS `mark` FROM `marks`
                                          UNION ALL
                                          SELECT `student_id`, `Name`, `mark3` AS `mark` FROM `marks`
                                          UNION ALL
                                          SELECT `student_id`, `Name`, `mark4` AS `mark` FROM `marks`
                                          UNION ALL
                                          SELECT `student_id`, `Name`, `mark5` AS `mark` FROM `marks`) AS `marks`
ORDER BY `mark` DESC
LIMIT 2