解释这个的最好方法是通过一个例子。让我们说我有这个简单的2列表:
Id | Score
1 | 10
2 | 5
3 | 20
4 | 15
5 | 20
6 | 25
7 | 30
8 | 30
9 | 10
10 | 40
查询应返回最大分数发生变化的每个项目的ID。因此,从顶部开始,10个将是最高分,因为第1项第一次通过10但是然后在第3项它得分为20,所以它只有一个新的最大分数并且这一直持续到表的底部。所以最终,查询将导致:
1, 3, 6, 7, 10
我尝试了Cursor并在表格中循环,但我想知道是否有一种简单的方法可以做到这一点。
由于
答案 0 :(得分:3)
解决方案(SQL2012 +):
SELECT v.MaxScore, MIN(v.Id) AS FirstId
FROM (
SELECT *, MAX(t.Score) OVER(ORDER BY t.Id ASC) AS MaxScore
FROM @Table AS t
) v
GROUP BY v.MaxScore
<强> Demo 强>
答案 1 :(得分:3)
另一个版本,适用于版本&gt; = 2008,您可以移除申请以使其适用于2005年
;with cte
(Id , Score)
as
(
select 1 , 10 union all
select 2 , 5 union all
select 3 , 20 union all
select 4 , 15 union all
select 5 , 20 union all
select 6 , 25 union all
select 7 , 30 union all
select 8 , 30 union all
select 9 , 10 union all
select 10 , 40
)
select min(id)
from
cte c2
cross apply
(select case when score -(select max(score) from cte c1 where c1.id<=c2.id )=0
then 1 else 0 end) b(val)
where val=1
group by Score
输出
1
3
6
7
10
答案 2 :(得分:0)
我认为您可以使用MIN
对ID进行GROUP BY Score
。像这样:
SELECT MIN(Id) FROM table GROUP BY Score
答案 3 :(得分:0)
使用LAG函数返回得分的上一个值:
DECLARE @Table TABLE(Id int, Score int)
INSERT INTO @Table
VALUES
(1 , 10),
(2 , 10),
(3 , 20),
(4 , 20),
(5 , 20),
(6 , 25),
(7 , 30),
(8 , 30),
(9 , 30),
(10 , 40)
SELECT *
FROM
(
SELECT
*,
LAG(t.Score, 1, NULL) OVER (ORDER BY t.Id) AS PrevScore
FROM @Table AS t
) AS p
WHERE p.Score <> p.PrevScore OR p.PrevScore IS NULL
答案 4 :(得分:0)
试试这个
declare @scores varchar(max)
select @scores = isnull(@scores+',','')+convert(varchar,min(id))
from #temp group by score
select @scores