【问题标题】:find second lowest value between multiple columns在多列之间找到第二个最低值
【发布时间】:2018-05-03 19:02:35
【问题描述】:

我有一个名为“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          |
|咪咪| 50.0 | 80.0   | 76.0   | 30.0   | 50.0  | 50.0          |

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

【问题讨论】:

  • 所以要理解这个问题,您是说要显示所有学生的分数,但他们的分数总是按从左到右的顺序排列,比如说?还是只针对那个学生?
  • 所有学生@Toby.. 每个学生都有每个“分数列”的分数记录。所以我想要一个查询,该查询只能选择所有分数列中的第二低分数并将值返回到该学生的“2nd_lowest”列中。这应该发生在所有学生身上。
  • 这似乎不是一个好的设计,要实现它你需要一个触发器。但由于您需要的数据是衍生数据,因此您实际上不必存储它
  • 我同意您的方法似乎有缺陷,以后可能会造成更多麻烦。我不明白为什么你会在每行中存储两次相同的值,只是为了显示第二低的值?为什么不直接查询数据库并查找第二低的呢?但是,要回答实际问题,您可以通过触发器来完成,正如 anchreg 所说。或者您可以尝试 CASE 语句,或者其他方法。用代码比用 SQL 更容易。试试看这里stackoverflow.com/questions/368351/… 可以吗?
  • select min(score1,score2,score3,score4,score5) 能够在所有五列中找到学生的最低值,并对表中的所有学生做同样的事情......我只是希望有办法找到第二低的@anchreg

标签: java sql sqlite


【解决方案1】:
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
    ) 
)

【讨论】:

  • 感谢@Mike,但 sqlite3 dbms 不接受查询语句,因为它以“with”开头.. 我理解它是一个实际的 mysql 查询语句。有没有办法在 sqlite 3 dbms 中编写要接受的语句
  • @RodneyNart 更新了,试试看
  • 感谢您的努力@Mike ..我仍然在查询中的“来自测试 T”周围遇到异常..异常是 'Java.sql.SQLException: 在“测试”附近:语法错误'..我尝试解决该区域,但仍然出现异常..请您帮帮我..非常感谢。
  • @RodneyNart 将“test”重命名为你的表。你的 Sqlite 版本是什么?
  • 是的,我做到了.. 我正在使用 sqlite manager.. 数据库扩展名是 sqlite3。所以我的数据库名称是 db.sqlite3 @Mike。我的表名是 jh2。所以异常错误是'Java.sql.SQLException:靠近“jh2”:语法错误'兄弟。
【解决方案2】:

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

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

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

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];
        }

    }

希望能给大家一点帮助

【讨论】:

  • 感谢@Owen Fanz,我也会尝试这种方法.. 谢谢
【解决方案3】:

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

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;

【讨论】:

  • ohh @Toby 我阅读了您提供的 CASE 声明链接...我还没有尝试过。我感谢所有的帮助。谢谢。
  • 'Java.sql.SQLException: only a single result allowed for a SELECT that is part of a expression'是我得到@Tom Mac的异常错误
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-07
  • 2011-01-28
  • 1970-01-01
相关资源
最近更新 更多