Mysql中最高记录点数

时间:2013-09-09 10:55:27

标签: mysql

我的表

+------+-------+--------+
| NAME | MARKS | POINTS |
+------+-------+--------+
| S1   |    53 | (null) |
| S2   |    55 | (null) |
| S3   |    56 | (null) |
| S4   |    55 | (null) |
| S5   |    52 | (null) |
| S6   |    51 | (null) |
| S7   |    53 | (null) |
+------+-------+--------+

参考:http://www.sqlfiddle.com/#!2/5d046/1

我想在最高分上加3,2,1分。这里S3到3点,S2,S4到2点,S1,S7到1点。

最终输出看起来,

+------+-------+--------+
| NAME | MARKS | POINTS |
+------+-------+--------+
| S1   |    53 |   1    |
| S2   |    55 |   2    |
| S3   |    56 |   3    |
| S4   |    55 |   2    |
| S5   |    52 |   0    |
| S6   |    51 |   0    |
| S7   |    53 |   1    |
+------+-------+--------+

Plz帮助

4 个答案:

答案 0 :(得分:4)

我的建议是,您首先计算每个标记的排名,然后在更新中的案例陈述中使用它。

以下查询显示了计算排名的一种方法:

select t.*,
       @rn := if(@marks = marks, @rn, @rn + 1) as ranking,
       @marks := marks
from myTable t cross join
     (select @rn := 0, @marks := -1) const
order by t.marks desc;

(注意:我对这个方法有点不舒服,因为MySQL不保证用常量评估两个表达式的顺序。如果在@marks之前设置@rn,那么它在实践中,这似乎不会发生。并且,这与相关子查询的等价物更有效。)

然后,您可以使用update

将其加入join
update myTable join
       (select t.*,
               @rn := if(@marks = marks, @rn, @rn + 1) as ranking,
               @marks := marks
        from myTable t cross join
             (select @rn := 0, @marks := -1) const
        order by t.marks desc
       ) mr
       on myTable.Name = mr.Name
    set myTable.Points := (case when mr.ranking = 1 then 3
                                when mr.ranking = 2 then 2
                                when mr.ranking = 3 then 1
                                else 0
                           end);

已在您的SQL Fiddle上测试过。

答案 1 :(得分:1)

UPDATE myTable t1
INNER JOIN 
(
SELECT @row:=@row-1 AS RowPoints, Marks
FROM (
  SELECT Marks
  FROM myTable
  GROUP BY Marks
  ORDER BY Marks DESC
  LIMIT 3
) AS TopMarks
INNER JOIN (SELECT @row:=4) AS RowInit
) AS AddPoints ON t1.Marks = AddPoints.Marks
SET Points = COALESCE(Points, 0) + AddPoints.RowPoints;

这应该可以正常工作。您应该并且在Marks列上进行索引。

答案 2 :(得分:1)

您可以通过变量(请参阅其他答案中的示例)或case

来完成
select 
  myTable.*,
  case
    when max1.marks is not null then 3
    when max2.marks is not null then 2
    when max3.marks is not null then 1
    else 0
  end as score
from
  myTable
  LEFT JOIN
  (select marks from myTable order by marks desc limit 1) AS max1
  ON myTable.marks=max1.marks
  LEFT JOIN
  (select marks from myTable order by marks desc limit 2,1) AS max2
  ON myTable.marks=max2.marks
  LEFT JOIN
  (select marks from myTable order by marks desc limit 3,1) AS max3
  ON myTable.marks=max3.marks;

可以找到演示here

答案 3 :(得分:1)

最简单的方法:

SELECT t.Name Name, t.Marks Marks,

 (CASE WHEN Marks = (Select max(marks) from mytable) THEN 3 ELSE 0 END+

CASE WHEN Marks = (Select min(marks) from (Select distinct marks 
    from mytable order by marks desc limit 2) a) THEN 2 ELSE 0 END+

CASE WHEN Marks = (Select min(marks) from (Select distinct marks 
    from mytable order by marks desc limit 3) b) THEN 1 ELSE 0 END)

AS `Points`
FROM mytable t;

<强> SQL Fiddle