SQL查询查找x行,将最高值向前移动,中间不包含较低的值
我有一张表,左边有两列。 我试图根据一些逻辑实现第三列 逻辑:如果我们选择日期1/1,并且在分数下降之前,继续日期将达到的最高分数将是3/1。得了12分。因此,作为HighestAchievedScore,我们将以1/1获得12分。等等 如果我们在一个下一个得分下降的日期,我的最高得分将是我的下一个得分。就像你在2014年1月3日看到的那样SQL查询查找x行,将最高值向前移动,中间不包含较低的值,sql,sql-server,Sql,Sql Server,我有一张表,左边有两列。 我试图根据一些逻辑实现第三列 逻辑:如果我们选择日期1/1,并且在分数下降之前,继续日期将达到的最高分数将是3/1。得了12分。因此,作为HighestAchievedScore,我们将以1/1获得12分。等等 如果我们在一个下一个得分下降的日期,我的最高得分将是我的下一个得分。就像你在2014年1月3日看到的那样 date score HighestAchieveScore 1/01/2014 10 12 2/01/2014 11
date score HighestAchieveScore
1/01/2014 10 12
2/01/2014 11 12
3/01/2014 12 10
4/01/2014 10 11
5/01/2014 11 9
6/01/2014 9 8
7/01/2014 8 9
8/01/2014 9 9
我希望我解释得足够清楚。
已经感谢您为解决此问题所做的每一项输入。我不确定这是否可行。。。。但这是一般概念 A.Date
WITH CTE as
(SELECT Date, Score, ROW_NUMBER() OVER(ORDER BY A.Date ASC) AS Row FROM tableName)
SELECT A.Date, A.Score, coalesce(c.score, Max(A.Score)) as HighestArchievedScore
FROM CTE A
LEFT JOIN CTE B
on A.Date < B.Date
LEFT JOIN CTE C
on A.Row+1=B.Row
and A.Score > C.Score
GROUP BY A.DATE,
A.SCORE
假设您希望计算第三列,可以像这样创建表或将该列添加到现有表中,使用函数确定第三列的值:
Create Function dbo.fnGetMaxScore(@Date Date)
Returns Int
As Begin
Declare @Ret Int
Select @Ret = Max(Score)
From YourTable
Where Date > @Date
Return @Ret
End
Create Table YourTable
(
Date Date,
Score Int,
HighestAchieveScore As dbo.fnGetMaxScore(Date)
)
这应适用于SQL Server 2012,但不适用于早期版本:
WITH cte AS (
SELECT date,
LEAD(score) OVER (ORDER BY date) nextScore
FROM yourTable
)
SELECT t.date, score,
CASE
WHEN nextScore < score THEN nextScore
ELSE (
SELECT ISNULL(MAX(t1.score), t.score)
FROM yourTable t1
JOIN cte ON t1.date = cte.date
WHERE t1.date > t.date
AND ISNULL(nextScore, 0) < score
)
END AS HighestAchieveScore
FROM yourTable t
JOIN cte ON t.date = cte.date
让我们制作一些测试数据:
DECLARE @Score TABLE
(
ScoreDate DATETIME,
Score INT
)
INSERT INTO @Score
VALUES
('01-01-2014', 10),
('01-02-2014', 11),
('01-03-2014', 12),
('01-04-2014', 10),
('01-05-2014', 11),
('01-06-2014', 9),
('01-07-2014', 8),
('01-08-2014', 9);
现在我们将对我们的行进行编号,然后链接到下一行,看看我们是否仍在上升
WITH ScoreRows AS
(
SELECT
s.ScoreDate,
s.Score,
ROW_NUMBER() OVER (ORDER BY ScoreDate) RN
FROM @Score s
),
ScoreUpDown AS
(
SELECT p.ScoreDate,
p.Score,
p.RN,
CASE WHEN p.Score < n.Score THEN 1 ELSE 0 END GoingUp,
ISNULL(n.Score, p.Score) NextScore
FROM ScoreRows p
LEFT JOIN ScoreRows n
ON n.RN = p.RN + 1
)
输出:
ScoreDate Score Test
2014-01-01 00:00:00.000 10 12
2014-01-02 00:00:00.000 11 12
2014-01-03 00:00:00.000 12 10
2014-01-04 00:00:00.000 10 11
2014-01-05 00:00:00.000 11 9
2014-01-06 00:00:00.000 9 8
2014-01-07 00:00:00.000 8 9
2014-01-08 00:00:00.000 9 9
结果在第三列。mssql的哪个版本?2008年,2012年?你是如何在第一次约会时获得12分的高分的,而当时唯一的分数只有10分?第三列是通过记录中的向前推导出的。如果我们想从1/1开始找到最高的得分。我们继续前进,直到比分下降。所以我们检索到的最高值是3/1上的12。这将使我们的最高得分在1/1的12分。这将不起作用,您正在寻找所有未来分数的最大值,此查询中的任何内容都不会考虑分数的下降。分数可以下降,然后高于本地最大值。更正此问题并不能解决此问题。然而,这是一个很好的方法。我知道现在我错过了分数下降的要求。你的CTE只输出两列日期和行。在SELECT子句中,您还引用了分数,这在CTE中不再存在。这也是处理函数的好方法。功能上与另一个答案相同的错误。请参见截图和其他答案
ScoreDate Score Test
2014-01-01 00:00:00.000 10 12
2014-01-02 00:00:00.000 11 12
2014-01-03 00:00:00.000 12 10
2014-01-04 00:00:00.000 10 11
2014-01-05 00:00:00.000 11 9
2014-01-06 00:00:00.000 9 8
2014-01-07 00:00:00.000 8 9
2014-01-08 00:00:00.000 9 9