2

我试图选择一列(GameScore)中除最低值之外的所有值,但是当有两个这个最低值时,我的代码将两者都排除在外(我知道它为什么这样做,我只是不知道如何更正它并包括两个最低值之一)。

代码看起来像这样:

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 回答 2

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。

于 2014-10-18T17:34:39.273 回答
1

您可以通过几种方式执行此操作,包括 @Ben 显示的内容。从主要是 SQL Server 的背景来看,我很好奇是否可以只使用 ROWNUM,并发现关于ROWNUM 与 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;

像 Ben 一样使用 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;
于 2014-10-18T18:51:10.937 回答