Второе по величине значение среди значений столбцов той же строки в SQL - PullRequest
0 голосов
/ 05 октября 2018

Пример данных:

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 голосов
/ 05 октября 2018

Используя 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

0 голосов
/ 05 октября 2018

Используйте выражение 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 ;

Это решение легко обобщается на любое количество столбцов.


и вариант без CASE с использованием GREATEST() и 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 ;
0 голосов
/ 05 октября 2018

Рассмотрим следующее, которое еще более обобщенно обобщается:

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 |
 +----+----------+-------+

В случае привязанных оценок это решение выбирает решение с меньшим значением "score_no".

0 голосов
/ 05 октября 2018

Предполагая, что нет связей, вы можете использовать большое 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;

В общем, этот тип вопросов предполагает проблему со структурой данных.Я подозреваю, что у вас действительно должна быть таблица с одной строкой на id и score (и, возможно, score число).Это обычно легче манипулировать в SQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...