2012-07-03 25 views
2

我有一个由三列组成的表格:日期,时间和价格。 '时间'栏大约是分钟的时间间隔,但不是每个分钟的时间间隔。我希望创建一个包含Date,FlooredTime,LastPriceInInterval的新表,其中FlooredTime =每个10分钟间隔开始时的时间,LastPriceInInterval是每个间隔内最大可用时间的价格。tsql在每个10分钟的时间间隔内返回最后一个价格

Old Table:       New Table: 

Date Time   Price  Date  FlooredTime LastPriceInInterval 
2012-05-10 02:50:00 1352.7  2012-05-10 02:40:00 1353.0 
2012-05-10 02:46:00 1353.0  2012-05-10 02:30:00 1353.5 
2012-05-10 02:45:00 1352.8    
2012-05-10 02:44:00 1353.2    
2012-05-10 02:43:00 1353.1    
2012-05-10 02:42:00 1353.2    
2012-05-10 02:40:00 1353.4    
2012-05-10 02:39:00 1353.5    
2012-05-10 02:38:00 1354.6    
2012-05-11 03:31:00 1355.0    
2012-05-11 03:29:00 1354.0    

这是我到目前为止,但现在我卡住了。看起来,内部select语句不喜欢在where子句中使用Max; MAX(日期部分(分,m1.Time)%10)。将非常感谢知道如何使用允许的语法来实现预期的结果。

SELECT TOP 1000 Date 
    ,DATEADD(minute,-DATEPART(minute,Time)%10 ,Time) as FlooredTime 
    ,(Select Price from dbo.MyData 
     where m3.Date = m1.Date 
     and DATEPART(hour, m3.Time) = DATEPART(hour, m1.Time) 
     and datepart(minute,m3.Time)/10 = Floor(datepart(minute,m1.Time)/10) 
     and datepart(minute,m3.Time)%10 = Max(datepart(minute,m1.Time)%10) 
     ) as LastPriceInInterval 
FROM dbo.MyData 
where DATEPART(minute,Time)%10 = 0 
order by Date Desc, Time Desc 

谢谢!

后期编辑 - 我稍后将结果用作合并表达式中的源表。

+0

'tsql'告诉我们它是SQL Server或Sybase,但是*您正在使用哪一个*,哪个版本*? –

+0

SQL express 2008R2 – Yugmorf

回答

2

您能否先确定间隔,获取每个间隔的最大时间,然后与表格一起获得价格?使用CTE你可以很容易地做到这一点:

;WITH intervals(Date, T1, MaxTime) AS (
SELECT 
    Date 
    , DATEADD(minute, -DATEPART(minute, Time)%10, Time) 
    , MAX(Time) AS MaxTime 
FROM dbo.MyData 
GROUP BY Date 
    , DATEADD(minute, -DATEPART(minute, Time)%10, Time) 
) 
SELECT t.Date AS Date, i.T1 AS Time, t.Price 
FROM dbo.MyData t 
INNER JOIN intervals i ON t.Date = i.Date AND t.Time = i.MaxTime 
ORDER BY Date DESC, Time DESC 
+1

'T2'是什么? –

+0

好点,'T2'是间隔的结束。我尝试使用'BETWEEN'声明,并忘记把它拿出来。我已经更新了我的答案,并提出了您的评论。 –

+0

谢谢!这确实会返回所需的数据,并且是一个有益的学习体验,可以帮助您了解如何使用它。我在原始问题中没有提到的是,我将使用返回的表作为合并语句中的源表。如果我理解正确,我不能使用CTE作为这个 – Yugmorf

1

你可以各自10分钟的时间间隔内,排名在Time相反的顺序排,然后挑选排名第一的:

WITH ranked AS (
    SELECT 
    *, 
    FlooredTime = DATEADD(MINUTE, -DATEDIFF(MINUTE, 0, Time) % 10, Time), 
    TimeRank = ROW_NUMBER() OVER (
     PARTITION BY DATEDIFF(MINUTE, 0, Time)/10 
     ORDER BY Time DESC 
    ) 
    FROM MyData 
) 
SELECT 
    Date, 
    FlooredTime, 
    LastPriceInInterval = Price 
FROM ranked 
WHERE TimeRank = 1 
ORDER BY 
    Date DESC, 
    FlooredTime DESC 
; 

Here's a SQL Fiddle demo为查询。

+0

这是一个有趣的方法来处理它。我不知道为什么,但是当我在我的大型数据集上运行它时,我只得到144行结果(不知道它与代码逻辑的关系如何,但是144 * 10min = 1天)。 – Yugmorf

+0

如果您的大型数据集代表整整一天,并且所有10分钟的时间间隔在每个数据集中至少有一行表示,那么144行肯定是我期望的查询结果。或者我错过了什么? –

相关问题