找出数据的局部最大值

Kim_liu 2014-09-12 11:32:04
--> 测试数据:[kim]
if object_id('[kim]') is not null drop table [kim]
go
create table kim(closeprice decimal(18, 3), FLG int)
insert [kim]
select 6.11,NULL union all
select 6.39,NULL union all
select 6.51,NULL union all
select 6.4,NULL union all
select 6.39,NULL union all
select 5.5,NULL union all
select 5.63,NULL union all
select 5.64,NULL union all
select 5.62,NULL union all
select 5.64,NULL union all
select 5.64,NULL union all
select 5.65,NULL union all
select 5.65,NULL union all
select 5.48,NULL union all
select 5.4,NULL

/*
目标:希望设置FLG一列的标志,
设置规则为:如果一条记录a的值比前后2条记录的值都大,则设置FLG为1;
如果前面两条记录中有跟记录a一样大的值的时候,则把一样大的那条记录忽略,往前再多比较一条记录,直到有两条记录比记录a小。
如果后面两条记录中有跟记录a一样大的值的时候,则把一样大的那条记录忽略,往后再多比较一条记录,直到有两条记录比记录a小。
满足条件的FLG设置为1。

期望结果:
closeprice FLG
6.110 NULL
6.390 NULL
6.510 1 ---因为6.51大于前面2条,也大于后面2条,设置为1;
6.400 NULL
6.390 NULL
5.500 NULL
5.630 NULL
5.640 NULL ---这条不能设置标志位,大于前面两条,但不大于后面2条,因为后面两个5.64都要忽略,剩下两个是5.62,5.65
5.620 NULL
5.640 NULL
5.640 NULL
5.650 1 ---因为大于前面两条5.64,5.64,后面一条有5.65,一样大,则忽略该条,5.65大于5.48,5.40,设置为1
5.650 NULL
5.480 NULL
5.400 NULL
*/
...全文
223 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
Kim_liu 2014-09-12
  • 打赏
  • 举报
回复
版主都说难写,看来没戏了。
xjpolarbear 2014-09-12
  • 打赏
  • 举报
回复
用游标应该可以,就是比较笨.
--小F-- 2014-09-12
  • 打赏
  • 举报
回复
力气活。难写出来哦。
Kim_liu 2014-09-12
  • 打赏
  • 举报
回复
引用 8 楼 Tiger_Zhao 的回复:
id=13不想打标志,只需要将 p1 中的 AND p1.closeprice <> c.closeprice 语句去掉即可。
多谢多谢,看了好一会,才看明白。 非IT人员,股民而已,SQL水平非常有限。 看了你的答案,我想我能解决我的实际问题了。 实际情况比你程序能处理的情况简单, 谢谢!
Tiger_Zhao 2014-09-12
  • 打赏
  • 举报
回复
id=13不想打标志,只需要将 p1 中的 AND p1.closeprice <> c.closeprice 语句去掉即可。
Kim_liu 2014-09-12
  • 打赏
  • 举报
回复
引用 5 楼 Tiger_Zhao 的回复:
-- 加了id有次序
我期望如果有连续多个标志的时候,保留一个即可。 从结果来看,符合我的预期。多谢多谢。
Kim_liu 2014-09-12
  • 打赏
  • 举报
回复
引用 5 楼 Tiger_Zhao 的回复:
-- 加了id有次序
多谢多谢,数据本来是按时间排序的。
Tiger_Zhao 2014-09-12
  • 打赏
  • 举报
回复
-- 加了id有次序
Tiger_Zhao 2014-09-12
  • 打赏
  • 举报
回复
-- 加了id怎么有次序
create table #kim(id int identity(1,1),closeprice decimal(18, 3), FLG int)
insert #kim(closeprice,FLG)
select 6.11,NULL union all
select 6.39,NULL union all
select 6.51,NULL union all
select 6.4,NULL union all
select 6.39,NULL union all
select 5.5,NULL union all
select 5.63,NULL union all
select 5.64,NULL union all
select 5.62,NULL union all
select 5.64,NULL union all
select 5.64,NULL union all
select 5.65,NULL union all
select 5.65,NULL union all
select 5.48,NULL union all
select 5.4,NULL
go

WITH p1 AS (
SELECT id, closeprice, p1id
FROM (
SELECT c.id, c.closeprice,
p1.id p1id, p1.closeprice p1closeprice,
ROW_NUMBER() OVER (PARTITION BY c.id ORDER BY p1.id DESC) n
FROM #kim c
JOIN #kim p1
ON p1.id < c.id
AND p1.closeprice <> c.closeprice
) T
WHERE n = 1
AND p1closeprice < closeprice
),
p2 AS (
SELECT id, closeprice, p2id
FROM (
SELECT c.id, c.closeprice,
p2.id p2id, p2.closeprice p2closeprice,
ROW_NUMBER() OVER (PARTITION BY c.id ORDER BY p2.id DESC) n
FROM p1 c
JOIN #kim p2
ON p2.id < c.p1id
AND p2.closeprice <> c.closeprice
) T
WHERE n = 1
AND p2closeprice < closeprice
),
n1 AS (
SELECT id, closeprice, n1id
FROM (
SELECT c.id, c.closeprice,
n1.id n1id, n1.closeprice n1closeprice,
ROW_NUMBER() OVER (PARTITION BY c.id ORDER BY n1.id) n
FROM #kim c
JOIN #kim n1
ON n1.id > c.id
AND n1.closeprice <> c.closeprice
) T
WHERE n = 1
AND n1closeprice < closeprice
),
n2 AS (
SELECT id, closeprice, n2id
FROM (
SELECT c.id, c.closeprice,
n2.id n2id, n2.closeprice n2closeprice,
ROW_NUMBER() OVER (PARTITION BY c.id ORDER BY n2.id) n
FROM n1 c
JOIN #kim n2
ON n2.id > c.n1id
AND n2.closeprice <> c.closeprice
) T
WHERE n = 1
AND n2closeprice < closeprice
)
/*
SELECT k.*,
p1.p1id, p2.p2id,
n1.n1id, n2.n2id
FROM #kim k
FULL OUTER JOIN p1 ON p1.id = k.id
FULL OUTER JOIN p2 ON p2.id = k.id
FULL OUTER JOIN n1 ON n1.id = k.id
FULL OUTER JOIN n2 ON n2.id = k.id
*/
UPDATE #kim
SET FLG = 1
FROM #kim, p2, n2
WHERE #kim.id = p2.id
AND #kim.id = n2.id

SELECT *
FROM #kim

         id                              closeprice         FLG
----------- --------------------------------------- -----------
1 6.110 NULL
2 6.390 NULL
3 6.510 1
4 6.400 NULL
5 6.390 NULL
6 5.500 NULL
7 5.630 NULL
8 5.640 NULL
9 5.620 NULL
10 5.640 NULL
11 5.640 NULL
12 5.650 1
13 5.650 1
14 5.480 NULL
15 5.400 NULL

id=13 也符合吧,给出的期望结果不正确!

34,587

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧