2014-10-18 3 views
2

Я пытаюсь выбрать все, кроме самого низкого значения в столбце (GameScore), но когда есть два из этих самых низких значений, мой код исключает оба (я знаю, почему он это делает, Я просто не знаю точно, как исправить это и включить одно из двух самых низких значений).Исключая только одно значение MIN для Oracle SQL

код выглядит примерно так:

SELECT Id, SUM(Score)/COUNT(Score) AS Score 
FROM 
    (SELECT Id, Score 
    FROM GameScore 
    WHERE Game_No = 1 
     AND Score NOT IN 
     (SELECT MIN(Score) 
     FROM GameScore 
     WHERE Game_No = 1 
     GROUP BY Id)) 
GROUP BY Id 

Так что, если я рисую из 5 значений, но одна из строк тянет только 3 балла, потому что дно две такие же, как я включаю 4-й ? Благодарю.

ответ

4

Для этого вам нужно как-то разделить их; ваша текущая проблема заключается в том, что 2 младших балла одинаковы, поэтому любая операция равенства (в), выполняемая по любым значениям, относится к другой одинаково.

Вы могли бы использовать что-то вроде аналитического запроса ROW_NUMBER() для однозначной идентификации строк:

select id, sum(score)/count(score) as score 
    from (select id, score, row_number() over (order by score) as score_rank 
      from gamescore 
      where gameno = 1 
       ) 
where score_rank <> 1 
group by id 

ROW_NUMBER():

присваивает уникальный номер для каждой строки, к которой она применяется (либо каждая строка раздел или каждая строка, возвращаемая запросом), в упорядоченной последовательности строк, указанных в order_by_clause, начиная с 1.

Поскольку предложение ORDER BY находится на SCORE в порядке возрастания, один из самых низких баллов будет удален. Это будет случайным значением, если вы не добавите другие условия тай-брейка в ORDER BY.

+0

Это сработало. Я также забыл критический фрагмент информации - что уже есть способ заказать разные баллы (назовем его Score_No). Я мог бы просто создать другой подзапрос и исключить один из тех Score_No. Этот ответ очень помог. Благодарю. – btalbot

1

Вы можете сделать это несколькими способами, в том числе и тем, что показывает @Ben. Из основного фона SQL Server мне было любопытно, можно ли использовать только ROWNUM и нашел этот фрагмент на ROWNUM vs ROW_NUMBER интересным. Я не уверен, что это датировано.

Все в SQLFiddle.

Примечание: Я использую подзапрос факторинга/CTE, как я думаю, более четко, чем в строковых подзапросах.

Использование ROWNUM:

WITH OrderedScore AS (
    SELECT id, game_no, score 
     ,rownum as score_rank 
    FROM GameScore 
    WHERE game_no = 1 
    ORDER BY Score ASC 
)  
SELECT id 
     ,sum(score)/count(score) 
    FROM OrderedScore 
WHERE score_rank > 1 
GROUP BY id; 

Использование row_number() OVER (ORDER BY ...), как Бен делает:

WITH OrderedScore AS (
    SELECT id, game_no, score 
     ,ROW_NUMBER() OVER(ORDER BY score ASC) as score_rank 
    FROM GameScore 
    WHERE game_no = 1 
    ORDER BY Score ASC 
) 
SELECT id 
     ,sum(score)/count(score) 
    FROM OrderedScore 
WHERE score_rank > 1 
GROUP BY id; 

Использование row_number() OVER (PARTION BY ... ORDER BY ...), которые, как я думаю, приводят к большей гибкости, если вы хотите удалить низкий балл по game_no или id в какой-то момент:

WITH OrderedScore AS (
    SELECT id, game_no, score 
     ,ROW_NUMBER() OVER(PARTITION BY id ORDER BY score ASC) as score_rank 
    FROM GameScore 
    WHERE game_no = 1 
    ORDER BY Score ASC 
) 
SELECT id 
     ,sum(score)/count(score) 
    FROM OrderedScore 
WHERE score_rank > 1 
GROUP BY id; 

 Смежные вопросы

  • Нет связанных вопросов^_^