我从商品交易所获得了一份谨慎的历史交易清单,其中包括日期时间和价值。
tradeTime | price
-----------------------------------
2014-06-11T00:21:12+02:00 | 647.24
2014-06-11T00:23:12+02:00 | 700.18
2014-06-11T00:28:12+02:00 | 750.23
2014-06-11T00:40:00+02:00 | 767.81
2014-06-11T00:51:12+02:00 | 711.46
现在我希望能够每小时创建一个价格清单。因此,三种逻辑可能性是:
因此,使用上面的示例,查看10分钟的增量,输出应该类似于:
period | open | close
--------------------------------
00:20 -> 00:30 | 648.24 | 750.23
00:30 -> 00:40 | 750.23 | 767.81
00:40 -> 00:50 | 767.81 | 711.46
-
SELECT * FROM sales BETWEEN From_date AND To_date
可能有MIN()
,MAX()
日期来选择价格?
答案 0 :(得分:1)
尝试此查询:
WITH qq AS (
SELECT cast('2014-06-11T00:00:00' as datetime) as startTime,
dateadd( minute, 10, cast('2014-06-11T00:00:00' as datetime)) as endTime
UNION ALL
SELECT endTime, dateadd( minute, 10, endTime )
FROM qq
WHERE endTime < cast('2014-06-12T00:00:00' as datetime)
)
SELECT startTime, endTime,
coalesce( opening, opening1 ) as opening,
coalesce( closing, opening, opening1 ) as closing
FROM (
SELECT qq.startTime, qq.endTime,
(SELECT TOP 1 price FROM table1 t1
WHERE t1.tradeTime >= qq.startTime AND t1.tradeTime < qq.endTime
ORDER BY t1.tradeTime ) As opening,
(SELECT TOP 1 price FROM table1 t1
WHERE t1.tradeTime >= qq.startTime AND t1.tradeTime < qq.endTime
ORDER BY t1.tradeTime DESC ) As closing,
(SELECT TOP 1 price FROM table1 t1
WHERE t1.tradeTime < qq.startTime
ORDER BY t1.tradeTime DESC ) as opening1
FROM qq
) x
option (maxrecursion 0)
演示:http://sqlfiddle.com/#!18/b9363/6
| startTime | endTime | opening | closing |
|----------------------|----------------------|---------|---------|
| 2014-06-11T00:00:00Z | 2014-06-11T00:10:00Z | (null) | (null) |
| 2014-06-11T00:10:00Z | 2014-06-11T00:20:00Z | (null) | (null) |
| 2014-06-11T00:20:00Z | 2014-06-11T00:30:00Z | 647.24 | 750.23 |
| 2014-06-11T00:30:00Z | 2014-06-11T00:40:00Z | 750.23 | 750.23 |
| 2014-06-11T00:40:00Z | 2014-06-11T00:50:00Z | 767.81 | 767.81 |
| 2014-06-11T00:50:00Z | 2014-06-11T01:00:00Z | 711.46 | 711.46 |
| 2014-06-11T01:00:00Z | 2014-06-11T01:10:00Z | 711.46 | 711.46 |
| 2014-06-11T01:10:00Z | 2014-06-11T01:20:00Z | 711.46 | 711.46 |
| 2014-06-11T01:20:00Z | 2014-06-11T01:30:00Z | 711.46 | 711.46 |
| 2014-06-11T01:30:00Z | 2014-06-11T01:40:00Z | 711.46 | 711.46 |
| 2014-06-11T01:40:00Z | 2014-06-11T01:50:00Z | 711.46 | 711.46 |
| 2014-06-11T01:50:00Z | 2014-06-11T02:00:00Z | 711.46 | 711.46 |
...
...
...
答案 1 :(得分:0)
您需要从小时列表开始。因为您可能没有交易,所以您需要生成此交易。假设你只需要几个小时 - 比如一天中的所有小时 - 一个递归的CTE就足够了:
with hours as (
select cast('2014-06-11' as datetime) as yyyymmddhh
union all
select dateadd(hour, 1, yyyymmddhh)
from hours
where dateadd(hour, 1, yyyymmddhh) < '2014-06-12'
)
然后,您可以使用apply
:
with hours as (
select cast('2014-06-11' as datetime) as yyyymmddhh
union all
select dateadd(hour, 1, yyyymmddhh)
from cte
where dateadd(hour, 1, yyyymmddhh) < '2014-06-12'
)
select h.*, opening.price, closing.price
from hours h outer apply
(select top 1 t.*
from t
where tradetime < dateadd(hour, 1, yyyymmddhh)
order by (case when cast(tradetime as date) = cast(yyyymmddhh as date) and
datepart(hour, tradetime) = datepart(hour, yyyymddhh)
then 1
else 0
end),
(case when cast(tradetime as date) = cast(yyyymmddhh as date) and
datepart(hour, tradetime) = datepart(hour, yyyymddhh)
then tradetime
end) asc,
tradetime desc
) opening outer apply
(select top 1 t.*
from t
where tradetime < dateadd(hour, 1, yyyymmddhh)
order by (case when cast(tradetime as date) = cast(yyyymmddhh as date) and
datepart(hour, tradetime) = datepart(hour, yyyymddhh)
then 1
else 0
end),
tradetime desc
) closing;
答案 2 :(得分:0)
下午好,
我不确定我的解决方案是否真的对您有所帮助,因为我不能检查代码是否有效或者为什么没有,我会尝试这些行:
SELECT prices FROM trades WHERE(SELECT MIN(DATEPART(MINUTE, trades.dates)),
MAX(DATEPART(MINUTE, trades.dates)) WHERE(SELECT DISTINCT DATEPART(HOUR,
trades.dates));
这个想法是在每个不同的小时内查询分钟的最小值和最大值,然后查询分钟1和分钟60的相关价格,以便获得开盘价和收盘价。
我希望这有助于您继续解决问题,或者至少为您提供可能的解决方案。
祝福,
M.S。
答案 3 :(得分:0)
以下查询应该给你一个开始。
SELECT DISTINCT Disp,
(
CASE WHEN [Open] IS NOT NULL THEN [Open]
ELSE (SELECT TOP 1 PRICE FROM @Table
WHERE Datepart(MINUTE, TradeTime) / 10 < O.Diff )
END
) AS [Open]
,(
CASE WHEN O.[Open] IS NOT NULL THEN [Open]
ELSE (SELECT TOP 1 PRICE FROM @Table
WHERE Datepart(MINUTE, TradeTime) / 10 < O.Diff )
END
) AS [Close]
FROM
(
SELECT
D.Disp
,D.Diff
,FIRST_VALUE(Price) OVER (PARTITION BY GRP
ORDER BY TradeTime ASC) AS [Open]
,FIRST_VALUE(Price) OVER (PARTITION BY GRP
ORDER BY TradeTime DESC) AS [Close],
TradeTime
FROM (VALUES (0,'00:01->00:10'),
(1,'00:10->00:20'),
(2,'00:20->00:30'),
(3,'00:30->00:40'),
(4,'00:40->00:50'),
(5,'00:50->00:59')
) D(Diff,Disp)
LEFT JOIN (SELECT Datepart(MINUTE, TradeTime) / 10 AS GRP,
TradeTime,
Price
FROM @Table
GROUP BY Datepart(MINUTE, TradeTime) / 10,
TradeTime,
Price) T
ON T.GRP = D.Diff
) O
完成示例:
DECLARE @Table TABLE(TradeTime DATETIME, Price DECIMAL(15,2))
INSERT INTO @Table
SELECT * FROM
(VALUES
(CAST('2018-02-18 13:04:46.920' AS DATETIME) , 647.24)
,(CAST('2018-02-18 13:05:46.920' AS DATETIME) , 700.18)
,(CAST('2018-02-18 13:15:46.920' AS DATETIME) , 750.23)
,(CAST('2018-02-18 13:24:46.920' AS DATETIME) , 767.81)
,(CAST('2018-02-18 14:26:46.920' AS DATETIME) , 711.46)
) TAB(TradeTime, Price)
SELECT DISTINCT Disp,
(
CASE WHEN [Open] IS NOT NULL THEN [Open]
ELSE (SELECT TOP 1 PRICE FROM @Table
WHERE Datepart(MINUTE, TradeTime) / 10 < O.Diff )
END
) AS [Open]
,(
CASE WHEN O.[Open] IS NOT NULL THEN [Open]
ELSE (SELECT TOP 1 PRICE FROM @Table
WHERE Datepart(MINUTE, TradeTime) / 10 < O.Diff )
END
) AS [Close]
FROM
(
SELECT
D.Disp
,D.Diff
,FIRST_VALUE(Price) OVER (PARTITION BY GRP
ORDER BY TradeTime ASC) AS [Open]
,FIRST_VALUE(Price) OVER (PARTITION BY GRP
ORDER BY TradeTime DESC) AS [Close],
TradeTime
FROM (VALUES (0,'00:00->00:10'),
(1,'00:10->00:20'),
(2,'00:20->00:30'),
(3,'00:30->00:40'),
(4,'00:40->00:50'),
(5,'00:50->00:59')
) D(Diff,Disp)
LEFT JOIN (SELECT Datepart(MINUTE, TradeTime) / 10 AS GRP,
TradeTime,
Price
FROM @Table
GROUP BY Datepart(MINUTE, TradeTime) / 10,
TradeTime,
Price) T
ON T.GRP = D.Diff
) O
示例输出
Disp Open Close
--------------------------------------
00:00->00:10 647.24 647.24
00:10->00:20 750.23 750.23
00:20->00:30 767.81 767.81
00:30->00:40 647.24 47.24
00:40->00:50 647.24 647.24
00:50->00:59 647.24 647.24