我正在尝试选择列中最低值(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个?感谢。
答案 0 :(得分:4)
为了做到这一点,你必须以某种方式将它们分开;您当前的问题是2个最低分数是相同的,因此对任一值执行的任何(in)相等操作都相同地处理另一个值。
您可以使用类似分析查询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添加其他违规条件,否则这将是一个随机值。
答案 1 :(得分: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;
像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;