我的表
+------+-------+--------+
| 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帮助
答案 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 强>