找到多列之间的第二低值

时间:2017-11-20 14:14:10

标签: java sql sqlite

我有一个名为'dbTable'的数据库表,有7列,分别是:name,score1,score2,score3,score4,score5,2nd_lowest。 每个学生都有一个记录,其中填写了所有分数列。

eg//
If james had 'score1' =  40, 'score2' = 70, 'score3' = 36, 'score4' = 60, 'score5' =  50.

如何编写SQL查询以选择40作为第二小分值并将其更新为第二低分列。
以便其余记录可以填写“2nd_lowest”,如下所示:

|名字|得分1 |得分2 |得分3 |得分4 |得分5 | 2nd_lowest |
-------------------------------------------------- -----------------------------------
|吉米| 40.0 | 70.0 | 36.0 | 60.0 | 50.0 | 40.0 |
|凯恩| 20.0 | 90.0 | 72.0 | 10.0 | 30.0 | 20.0 |
| mimy | 50.0 | 80.0 | 76.0 | 30.0 | 50.0 | 50.0 |

我正在使用sqlite3 dbms
所有帮助将不胜感激。谢谢

3 个答案:

答案 0 :(得分:1)

嗯。如果可能的话,我会重新考虑你的数据库设计。但如果你不能,那么这应该让你朝着正确的方向前进。是的,这很可怕,但数据表也是一个棘手的问题!

select name,min(s1,s2,s3,s4,s5) as second_least
from
(
 select dt.name,
 case when score1=min(score1,score2,score3,score4,score5) then max(score1,score2,score3,score4,score5) else score1 end as s1,
 case when score2=min(score1,score2,score3,score4,score5) then max(score1,score2,score3,score4,score5) else score2 end as s2,
 case when score3=min(score1,score2,score3,score4,score5) then max(score1,score2,score3,score4,score5) else score3 end as s3,
 case when score4=min(score1,score2,score3,score4,score5) then max(score1,score2,score3,score4,score5) else score4 end as s4,
 case when score5=min(score1,score2,score3,score4,score5) then max(score1,score2,score3,score4,score5) else score5 end as s5
 from  dbTable dt
) t;

答案 1 :(得分:1)

这假设你可以使用一些Java:

如何将一个人的所有分数从db存储到一个数组列表然后迭代它以找到第二个最低值然后将该值的输出插入到该人的2nd_lowest列?

这样的东西可以找到数组中的第二低,你当然可以适应使用DB中的值:

double[] elements = {40.0  70.0  36.0, 60.0, 50.0};
    double smallest = Integer.MAX_VALUE;
    double secondSmallest = Integer.MAX_VALUE;
    for (double i = 0; i < elements.length; i++) {
    if (elements[i] < smallest) {
            secondSmallest = smallest;
            smallest = elements[i];
        } else if (elements[i] < secondSmallest) {
            secondSmallest = elements[i];
        }

    }

希望能提供一些帮助

答案 2 :(得分:0)

with num(x) as(
  values(1),(2),(3),(4),(5)
),
new as(
 select name, case x when 1 then score1  when 2 then score2  when 3 then score3
                     when 4 then score4  else score5 end val
   from test, num
  where val!=min(score1,score2,score3,score4,score5)
)
update test set "2nd_lowest"=
   (select min(val) from new where new.name=test.name)

sqlfiddle.com上的演示

对于不支持CTE的旧版SQlite3:

update test set "2nd_lowest"=(
  select min(val)
    from (
      select name, case x when 1 then score1 when 2 then score2
                     when 3 then score3 when 4 then score4
                     else score5 end val
        from test T, (select 1 as x union all values(2),(3),(4),(5)) X
       where val!=min(score1,score2,score3,score4,score5)
         and T.name=test.name
    ) 
)