2017-10-06 113 views
0

我有一個SQL Server表中的一些數據如下最接近值:T-SQL查詢返回

DateTime    Bid  Ask 
02/10/2017 09:59.323 123.111 123.894 
02/10/2017 10:01.432 123.321 124.001 
02/10/2017 10:03.132 123.421 124.121 
02/10/2017 10:03.983 123.121 123.721 
02/10/2017 10:04.342 123.587 124.200 

我想查詢一下買入價和賣出值在每第二時間段。例如在:

  • 10:00.000價比123.111和詢問是123.894
  • 10:01.000價比123.111和詢問是123.894
  • 10:02.000價比123.321和問問爲124.001
  • 10:03.000價比123.321和詢問是124.001
  • 10:04.000價比123.121和詢問被123.721

所以SQL需求在每個第二個值之前返回「日期時間」的「出價」和「詢問」值。

例如爲:

  • 10:00.000使用09:59.323
  • 10:01.000使用09:59.323
  • 10:02.000使用10:01.432
  • 10:03.000使用10: 01.432
  • 10:04.000使用10:03.983

我的查詢將一個ST之間的返回值藝術和結束日期/時間,所以它會返回多行。

+0

你有第二日期/時間值,你要使用一個表?或者正在生成問題的列表部分? –

+0

我還沒有存儲第二個值的表(例如10:00.000,10:01.000,10:02.000等),因爲可能存在數年的存儲日期。所以我認爲這個清單應該是生成的。但我會知道顯示 –

+0

之間的值的日期/時間。我們如何知道列表中使用的範圍?而'10:01.000'並不是一個很好的時間參考。它有幾個小時(10),幾分鐘(:01),然後是毫秒(.000)。它完全跳過秒部分,並且Sql Server在您的文章中爲每個時間戳使用隱含的0值。你確定你不想要這個:'10:00:01.000'? –

回答

0

按日期時間降序對錶格進行排序,將返回值限制爲1,然後確保返回的值低於提供的日期時間。

[編輯]

select top 1 bid, ask 
from datatable 
where itsdatetime <= '02/10/2017 10:00.000' 
order by itsdatetime desc 

你可以得到更多的創意,並把條件的子查詢裏面。

select * 
from requiretimes rt 
join datatable dt on dt.itsdatetime = (select top 1 itsdatetime 
        from datatable 
        where itsdatetime <= rt.requireddatetime 
        order by itsdatetime desc) 
+0

你能舉個例子嗎?謝謝 –

0

你可以試試這個查詢:

if object_id('tempdb..#Table1') is not null 
    drop table #Table1 
go 
create table #Table1(
DateTime datetime 
,Bid float  
,Ask float) 

insert into #Table1 
select '02/10/2017 09:59.323', 123.111, 123.894 
union all select '02/10/2017 10:01.432', 123.321, 124.001 
union all select '02/10/2017 10:03.132', 123.421, 124.121 
union all select '02/10/2017 10:03.983', 123.121, 123.721 
union all select '02/10/2017 10:04.342', 123.587, 124.200 

declare @start_date datetime 
     , @end_date datetime 

select @start_date = dateadd(mi, datediff(mi, 0, min(DateTime)) + 1, 0) 
    from #Table1 

select @end_date = dateadd(mi, datediff(mi, 0, max(DateTime)), 0) 
    from #Table1 

;with generates_dates as(
select @start_date as dt 
union all 
select dateadd(mi, 1, dt) as dt 
    from generates_dates 
    where dt < @end_date) 

select t1.dt 
    , t2.Bid 
    , t2.Ask 
    from generates_dates t1 
    cross apply(select top 1 Bid, Ask 
        from #Table1 t2 
        where t2.DateTime < t1.dt 
        order by t2.DateTime desc)t2(Bid, Ask) 
    option (maxrecursion 0) 
0

有兩個部分是:

  1. 創建投影牽着你的時間戳:10:00.000,10:01.000 ,10:02.000等。這很難在這裏回答,因爲我們不知道你用什麼標準來確定你的開始和結束範圍,並且因爲你的問題要求回合秒,但您的時間戳值實際上顯示分鐘。如果你需要這方面的幫助,谷歌有很多結果,Stack Overflow用於創建預測,數字表或序列。

  2. 使用OUTER APPLY運算符將投影連接回原始數據。 OUTER APPLY可以很容易地顯示投影中每個項目的一條正確記錄。

WITH times As (
    SELECT cast('2017-02-10 10:00.000' as datetime) "DateTime" 
    UNION 
    SELECT cast('2017-02-10 10:01.00' as datetime) 
    UNION 
    SELECT cast('2017-02-10 10:02.000' as datetime) 
    UNION 
    SELECT cast('2017-02-10 10:03.000' as datetime) 
    UNION 
    SELECT cast('2017-02-10 10:04.000' as datetime) 
    UNION 
    SELECT cast('2017-02-10 10:05.000' as datetime) 
) 
SELECT t.[DateTime], u.[DateTime], u.Bid, u.Ask 
FROM times t 
CROSS APPLY ( 
     SELECT TOP 1 * 
     FROM [MyTable] 
     WHERE [DateTime] < t.[DateTime] 
     ORDER BY [DateTime] DESC 
) u 
ORDER BY t.[DateTime] 

SQLFiddle

0
DECLARE @T TABLE 
(
    d DateTime, 
    bid MONEY, 
    ask MONEY 
) 
INSERT INTO @T VALUES 
('02/10/2017 09:59.323', 123.111, 123.894), 
('02/10/2017 10:01.432', 123.321, 124.001), 
('02/10/2017 10:03.132', 123.421, 124.121), 
('02/10/2017 10:03.983', 123.121, 123.721), 
('02/10/2017 10:04.342', 123.587, 124.200), 
('03/10/2017 10:04.342', 123.587, 124.200) 

;WITH sec AS 
(
    SELECT TOP (SELECT 60*60*24) ROW_NUMBER() OVER (ORDER BY 1/0) as s 
    FROM master..spt_values a,master..spt_values m 
), dd as 
(
    SELECT DISTINCT CAST(d as date) as d 
    FROM @t 
), Tbl as 
(
    SELECT 
     DATEADD(ss,b.s,CAST(a.d as datetime)) as dat 
    FROM  
     dd a 
    CROSS JOIN 
     sec b 
) 
SELECT 
    dat 
    ,c.* 
FROM  tbl 
CROSS APPLY 
(
    SELECT TOP 1 * 
    FROM @t a 
    WHERE 
     a.d >= tbl.dat 
    ORDER BY 
     a.d ASC 
) as c 
WHERE 
    c.d >= dat AND 
ORDER BY dat 
0

你會產生秒遞歸查詢。 (由於SQL Server不支持ANSI時間戳文字,因此您需要CONVERT。)然後通過CROSS APPLY加入以從表中獲取每秒的最後一個條目。

with secs(sec) as 
(
    select convert(datetime, '2017-10-02 10:00:00', 20) as sec 
    union all 
    select dateadd(second, 1, sec) as sec 
    from secs 
    where sec <= convert(datetime, '2017-10-02 10:00:04', 20) 
) 
select secs.sec, data.bid, data.ask 
from secs 
cross apply 
(
    select top(1) * 
    from mytable 
    where mytable.datetime <= secs.sec 
    order by datetime desc 
) data; 

我按照您的描述使用秒數,而您的樣本使用分鐘數來代替。決定你實際需要的是什麼。

0

試試這個:

declare @idate datetime 
declare @fdate datetime 

select @idate = min(gendate) from BidAsk 
select @fdate = max(gendate) from BidAsk 

create table #temp (bid float, ask float, Gendate datetime) 

while (@idate <= @fdate) 
begin 
    insert into #temp 
    select top 1 Bid, Ask, @idate from BidAsk where @idate > GenDate 
    order by GenDate desc 

    set @idate = DATEADD(second,1,@idate) 
end 

select * from #temp