SQL中同一行的列值中的第二个最大值

时间:2018-10-05 16:20:34

标签: mysql sql

样本数据:

id score1 score2 score3 score4
1  10     05      30    50
2  05     15      10    00
3  25     10      05    15

预期结果集:

id col_value
1    30
2    10
3    15

4 个答案:

答案 0 :(得分:6)

使用CASE表达式告诉您在GREATEST()通话中要忽略的分数。

SELECT id,
    CASE GREATEST(score1, score2, score3, score4)
        WHEN score1 THEN GREATEST(score2, score3, score4)
        WHEN score2 THEN GREATEST(score1, score3, score4)
        WHEN score3 THEN GREATEST(score1, score2, score4)
        ELSE GREATEST(score1, score2, score3)
    END AS col_value
FROM your_table ;

此解决方案可以轻松地推广到任意数量的列。


,以及同时使用CASEGREATEST()且没有LEAST()的变体形式:

SELECT id,
    LEAST(
        GREATEST(score1, score2, score3),
        GREATEST(score2, score3, score4),
        GREATEST(score3, score4, score1),
        GREATEST(score4, score1, score2)
    ) AS col_value
FROM your_table ;

答案 1 :(得分:2)

考虑以下内容,仍然可以更轻松地进行概括:

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table 
(id INT NOT NULL
,score_no INT NOT NULL
,score INT NOT NULL
,PRIMARY KEY(id,score_no)
);

INSERT INTO my_table VALUES
(1, 1 ,10),
(1 ,2 ,05),
(1 ,3 ,30),
(1 ,4 ,50),
(2 ,1 ,05),
(2 ,2 ,15),
(2 ,3 ,10),
(2 ,4 ,00),
(3 ,1 ,25),
(3 ,2 ,10),
(3 ,3 ,05),
(3 ,4 ,15);

SELECT id
     , score_no
     , score 
  FROM 
     ( SELECT x.*
            , CASE WHEN @prev=id THEN @i:=@i+1 ELSE @i:=1 END rank
            , @prev:=id 
         FROM my_table x
            , (SELECT @prev:=null,@i:=0) vars 
        ORDER 
           BY id
            , score DESC
            , score_no 
     ) a
 WHERE rank = 2;
 +----+----------+-------+
 | id | score_no | score |
 +----+----------+-------+
 |  1 |        3 |    30 |
 |  2 |        3 |    10 |
 |  3 |        4 |    15 |
 +----+----------+-------+

如果得分并列,此解决方案将选择得分较低的得分。

答案 2 :(得分:1)

假设没有关系,则可以使用大的case表达式:

select t.*,
       (case when score1 > score2 and score1 > score3 and score1 < score 4 then score1
             when score1 > score2 and score1 < score3 and score1 > score 4 then score1
             when score1 < score2 and score1 > score3 and score1 > score 4 then score1
             when score2 > score1 and score2 > score3 and score2 < score 4 then score2
             when score2 > score1 and score2 < score3 and score2 > score 4 then score2
             when score2 < score1 and score2 > score3 and score2 > score 4 then score2
             . . .
        end) as second_score          
from t;

通常,这种类型的问题表明数据结构存在问题。我怀疑您确实应该有一个表,其中每个idscore(可能还有一个score号)都包含一行。通常,这在SQL中更容易操作。

答案 3 :(得分:0)

使用UNPIVOT尝试此查询

    CREATE TABLE #my_table
(id INT NOT NULL, score1 INT NOT NULL, score2 INT NOT NULL, score3 INT NOT NULL, score4 INT NOT NULL) 

INSERT INTO #my_table VALUES(1,  10,     05,      30,    50)
INSERT INTO #my_table VALUES(2,  05,     15,      10,    00)
INSERT INTO #my_table VALUES(3,  25,     10,      05,    15)

;WITH getHighestValue as (
SELECT id, Scores, ScoreText, ROW_NUMBER() OVER(PARTITION BY id ORDER BY Scores DESC) AS Ranks
FROM #my_table
UNPIVOT(
Scores for ScoreText in (score1,score2,score3,score4)
) unpiv
)
SELECT id, Scores as col_value 
FROM getHighestValue
WHERE Ranks = 2

结果:

enter image description here