日期:2014-05-17  浏览次数:20468 次

SQLServer查询出相邻两个数据水位值变化大于0.3且小于0.5的(0.3=<waterHeight=<0.5)所有信息

  求助!本人遇到一个问题,希望得到大侠,大牛,高手们的帮助!!!
问题描述SQLServer查询出相邻两个数据水位值变化大于0.3且小于0.5的(0.3=<waterHeight=<0.5)所有信息
数据库表为:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[testDate](
[getInfoTime] [datetime] NULL,
[waterHeight] [float] NULL
) ON [PRIMARY]

数据信息
2012-12-30 13:02:00.000 3.3
2012-12-30 13:04:00.000 3.6
2012-12-30 13:06:00.000 4.6
2012-12-30 13:08:00.000 4.7
2012-12-30 14:10:00.000 1000
2012-12-30 14:12:00.000 3.3
2012-12-30 14:14:00.000 3.7
2012-12-30 14:16:00.000 4
2012-12-30 14:18:00.000 4.3
2012-12-30 14:20:00.000 3.8
2012-12-30 14:22:00.000 6
想实现的效果为:
2012-12-30 13:02:00.000 3.3
2012-12-30 13:04:00.000 3.6
2012-12-30 14:12:00.000 3.3
2012-12-30 14:14:00.000 3.7
2012-12-30 14:16:00.000 4
2012-12-30 14:18:00.000 4.3
我的写法如下:
declare csr_testDate cursor  for SELECT waterHeight,getInfoTime FROM CH331081.dbo.testDate where getInfoTime>'2012-12-30 12:02:00.000' and getInfoTime<'2012-12-30 14:22:00.000'
open csr_testDate
declare @waterHeightPrev float 
declare @waterHeightCur float
declare @time datetime
set @waterHeightPrev = 0
set @waterHeightCur = 0
fetch next from csr_testDate into @waterHeightPrev,@time;
while @@fetch_status = 0
begin
    fetch next from csr_testDate into @waterHeightCur,@time;
    if  (@waterHeightCur-@waterHeightPrev>0.3 and @waterHeightCur-@waterHeightPrev<0.5)
    BEGIN
    print @waterHeightCur;
    print @time;
    END
--   if @@fetch_status = 0
-- goto flag
end
-- flag:
close csr_testDate
deallocate csr_testDate
发现结果错误!
sqlserver

------解决方案--------------------
;with cte as (
select ROW_NUMBER() over( order by [getInfoTime]) as id
,[getInfoTime],[waterHeight]
from [dbo].[testDate] 
)
select [getInfoTime],[waterHeight] from cte a
where exists (
select 1 from cte b
where (b.id=a.id - 1
or b.id = a.id + 1)
and abs(b.waterHeight - a.waterHeight) between 0.3 and 0.5
)
order by [getInfoTime]

------解决方案--------------------
知道原因了,是waterHeight 的数据类型问题,float存储是很不精确的,容易丢失小数,你如果有按这个字段比较的需求,不应该用float,改用定点数numeric(18,2)

如下查询就有这条数据
;with cte as (
select ROW_NUMBER() over( order by [getInfoTime]) as id
,[getInfoTime],[waterHeight]
from [dbo].[testDate] 
)
select [getInfoTime],[waterHeight] from cte a
where exists (
select 1 from cte b
where (b.id=a.id - 1
or&