我需要SQl服務器2005(SQL服務器管理工作室快遞)的查詢。 我有數據存儲爲1分鐘的時間範圍(每行1分鐘),每個表的列是ID,符號,日期時間,開放,高,低,關閉,音量。 我需要轉換(壓縮)到每個可能的多個時間幀,所以我們假設10分鐘,13,15等等。 提供詳細信息,如果有人可以幫忙。 謝謝 AlbertoSQL Server 2005中的數據聚合
回答
;WITH cte AS
(SELECT *,
(32 * CAST([DATETIME] AS INT)) + DATEPART(HOUR,[DATETIME]) + (DATEPART(MINUTE,[DATETIME])/15)/4.0 AS Seg
FROM prices
)
,cte1 AS
(
SELECT *,
ROW_NUMBER() OVER (PARTITION BY Symbol,Seg ORDER BY [DATETIME]) AS RN_ASC ,
ROW_NUMBER() OVER (PARTITION BY Symbol,Seg ORDER BY [DATETIME] DESC) AS RN_DESC
FROM cte
)
SELECT
Symbol,
Seg,
MAX(CASE WHEN RN_ASC=1 THEN [DATETIME] END) AS OpenDateTime,
MAX(CASE WHEN RN_ASC=1 THEN [OPEN] END) AS [OPEN],
MAX(High) High,
MIN(Low) Low,
SUM(Volume) Volume,
MAX(CASE WHEN RN_DESC=1 THEN [CLOSE] END) AS [CLOSE],
MAX(CASE WHEN RN_DESC=1 THEN [DATETIME] END) AS CloseDateTime
FROM cte1
GROUP BY Symbol,Seg
ORDER BY OpenDateTime
或另一種方法可能是值得的測試,看看它是否是任何更快。
DECLARE @D1 DATETIME
DECLARE @D2 DATETIME
DECLARE @Interval FLOAT
SET @D1 = '2010-10-18 09:00:00.000'
SET @D2 = '2010-10-19 18:00:00.000'
SET @Interval = 15
;WITH
L0 AS (SELECT 1 AS c UNION ALL SELECT 1),
L1 AS (SELECT 1 AS c FROM L0 A CROSS JOIN L0 B),
L2 AS (SELECT 1 AS c FROM L1 A CROSS JOIN L1 B),
L3 AS (SELECT 1 AS c FROM L2 A CROSS JOIN L2 B),
L4 AS (SELECT 1 AS c FROM L3 A CROSS JOIN L3 B),
Nums AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS i FROM L4),
Ranges AS(
SELECT
DATEADD(MINUTE,@Interval*(i-1),@D1) AS StartRange,
DATEADD(MINUTE,@Interval*i,@D1) AS NextRange
FROM Nums where i <= 1+CEILING(DATEDIFF(MINUTE,@D1,@D2)/@Interval))
,cte AS (
SELECT
*
,ROW_NUMBER() OVER (PARTITION BY Symbol,r.StartRange ORDER BY [DateTime]) AS RN_ASC
,ROW_NUMBER() OVER (PARTITION BY Symbol,r.StartRange ORDER BY [DateTime] DESC) AS RN_DESC
FROM Ranges r
JOIN prices p ON p.[DateTime] >= r.StartRange and p.[DateTime] < r.NextRange)
SELECT
Symbol,
MAX(CASE WHEN RN_ASC=1 THEN [DateTime] END) AS OpenDateTime,
MAX(CASE WHEN RN_ASC=1 THEN [Open] END) AS [Open],
MAX(High) High,
MIN(Low) Low,
SUM(Volume) Volume,
MAX(CASE WHEN RN_DESC=1 THEN [Close] END) AS [Close],
MAX(CASE WHEN RN_DESC=1 THEN [DateTime] END) AS CloseDateTime
FROM cte
GROUP BY Symbol,StartRange
ORDER BY OpenDateTime
感謝馬丁,但我得到錯誤:也許我可以提供一些示例xls數據從我的SQL數據庫,我可以想象這是很難正確編碼沒有數據的查詢。我可以在這裏附上檔案嗎?否則acepsut是我的Skype暱稱以及我的gmail.com帳戶 – 2010-10-18 14:55:55
你會得到什麼錯誤? (如果你想把數據放在某個地方,Google電子表格可能是個好地方?) – 2010-10-18 14:58:23
@Alberto - 這是在smirkingman的回答下面的評論更新。 – 2010-10-19 11:28:56
Alberto,看起來您需要SQL語句中的「Group By」子句(如Leppie所述)。所以,你應該更好地尋找它。
首先,您應該使用開始日期/結束日期/時間篩選要聚合的行,然後按照提及的條款對它們進行分組。
這裏是第一個link當我搜索「sql group by」關鍵字通過谷歌。
不是簡單的「分組依據」 - 打開和關閉值需要爲組中的第一行和相應的最後一行。或者說,至少這樣是對外匯數據:)
是的,它不是一個簡單的組。 – 2010-10-18 13:28:42
將採用存儲過程:首先提取MIN(日期時間),更漂亮,但這裏有一個素描:
WITH quarters(q) AS (
SELECT DISTINCT
15*CAST(DATEDIFF("n",'2000/01/01',dataora)/15 as Int) AS primo
FROM
Prezzi
)
SELECT
simbolo, DATEADD("n",q,'2000/01/01') AS tick,
MIN(minimo) AS minimo, MAX(massimo) AS massimo,
(SELECT
TOP 1 apertura FROM Prezzi P
WHERE
P.simbolo = simbolo AND
P.dataora >= DATEADD("n",q,'2000/01/01')
ORDER BY
P.dataora ASC
) as primaapertura,
(SELECT
TOP 1 chiusura FROM Prezzi P
WHERE
P.simbolo = simbolo AND
P.dataora < DATEADD("s",14*60+59,DATEADD("n",q,'2000/01/01'))
ORDER BY
P.dataora DESC
) as ultimachiusara,
SUM(volume)/COUNT(*) AS volumemedio
FROM
quarters INNER JOIN Prezzi
ON dataora BETWEEN DATEADD("n",q,'2000/01/01')
AND DATEADD("s",14*60+59,DATEADD("n",q,'2000/01/01'))
GROUP BY
simbolo, DATEADD("n",q,'2000/01/01')
ORDER BY
1, 2
WITH子句得到的15個分鐘的間隔列表,向下取整,在數據集(讓我們假設2000年前沒有)。 然後使用這些間隔按14:59間隔分組。 對於音量,您必須決定是要平均還是總計。
語法可能不太好,但你應該明白。
編輯:調整MIN(打開),MIN(關閉)接第一和最後。實際上,這並不會有太大變化,因爲開放和關閉的概念取決於知道報價產生的交易所與計算機收集數據的時間之間的時間差異。
另外,除非OP有來自所有交易所的實時信息的特權,否則所有報價都會延遲20分鐘。
EDIT(2):完全正確,FIRST和LAST是從我的IBM天> ;-)
解結轉現在使用具有ASC/DESC TOP的間隔內選擇第一個和最後報價。
你爲什麼要得到'MIN(open)'和'MIN(close) ? OP需要與每段的第一條記錄相關的「開放」價格和與每段最後一條記錄相關的「關閉」價格。 – 2010-10-18 15:29:37
懶惰。他的數據來自價格反饋。開盤和收盤在白天不能改變,它們是股票價格今天早上的第一件事,昨晚是最後一件事。 – smirkingman 2010-10-18 15:40:53
這確實有道理,但這不是OP在註釋中定義它的方式。 「關閉(在此時間段內的最後價格)」@Alberto - 你能澄清一下嗎? – 2010-10-18 15:51:07
Declare @tbl1MinENI Table
(ID int identity,
Simbolo char(3),
DataOra datetime,
Apertura numeric(15,4),
Massimo numeric(15,4),
Minimo numeric(15,4),
Chiusura numeric(15,4),
Volume int)
Insert Into @tbl1MinENI ( Simbolo, DataOra, Apertura, Massimo, Minimo, Chiusura, Volume)
Values
('ENI', '2010/10/18 09:00:00', 16.1100, 16.1800, 16.1100, 16.1400, 244015),
('ENI', '2010/10/18 09:01:00', 16.1400, 16.1400, 16.1300, 16.1400, 15692),
('ENI', '2010/10/18 09:02:00', 16.1400, 16.1500, 16.1400, 16.1500, 147035),
('ENI', '2010/10/18 09:03:00', 16.1500, 16.1600, 16.1500, 16.1600, 5181 ),
('ENI', '2010/10/18 09:04:00', 16.1600, 16.2000, 16.1600, 16.1900, 5134 ),
('ENI', '2010/10/18 09:05:00', 16.1900, 16.1900, 16.1800, 16.1800, 15040),
('ENI', '2010/10/18 09:06:00', 16.1900, 16.1900, 16.1600, 16.1600, 68867),
('ENI', '2010/10/18 09:07:00', 16.1600, 16.1600, 16.1600, 16.1600, 7606 ),
('ENI', '2010/10/18 09:08:00', 16.1500, 16.1500, 16.1500, 16.1500, 725 ),
('ENI', '2010/10/18 09:09:00', 16.1600, 16.1600, 16.1600, 16.1600, 81 ),
('ENI', '2010/10/18 09:10:00', 16.1700, 16.1800, 16.1700, 16.1700, 68594),
('ENI', '2010/10/18 09:11:00', 16.1800, 16.1800, 16.1800, 16.1800, 6619 )
Declare @nRowsPerGroup int = 3
;With Prepare as
(
Select datediff(minute, '2010/10/18 09:00:00', DataOra)/@nRowsPerGroup as Grp,
Row_Number() over (partition by datediff(minute, '2010/10/18 09:00:00', DataOra)/@nRowsPerGroup order by dataora) as rn,
*
From tbl1MinENI
), b as
(
Select a.Grp,
Min(a.DataOra) as GroupDataOra,
Min(ID) AperturaID,
max(a.Massimo) as Massimo,
Min(a.Minimo) as Minimo,
max(id) ChiusuraID,
sum(a.Volume) as Volume
From Prepare a
Group by Grp
)
Select b.grp,
b.GroupDataOra,
ta.Apertura,
b.Massimo,
b.Minimo,
tc.Chiusura,
b.Volume
From b
Inner Join tbl1MinENI ta on ta.ID=b.AperturaID
Inner Join tbl1MinENI tc on tc.ID=b.ChiusuraID
;
謝謝尼古拉,我得到一些錯誤1)消息102級15行13錯誤的sintax','2)信息139級15行不可能將預定義的值分配給局部變量3)消息137級別15行30聲明標量值「@nRowsPerGroup」。 – 2010-10-19 12:39:41
如果缺少09:00:00的記錄,請執行此操作(請參閱前面的註釋) – smirkingman 2010-10-19 13:33:58
它有效。只需刪除09:00:00的插入並嘗試。事實上,你可以刪除任何數量的行,你想它仍然會工作。 – Niikola 2010-10-26 16:45:17
- 1. Sql Server的聚合函數
- 2. 複合聚集索引和非聚集索引在sql server 2005
- 3. SQL Server 2005-數據計數
- 4. SQL Server中的多個聚合函數
- 5. SQL Server中的聚合函數
- 6. Sql Server 2005數據類型
- 7. SQL Server 2005數據加密
- 8. SQL Server 2005中的XML數據導入
- 9. SQL Server 2005中的XML數據類型
- 10. 轉換SQL Server 2008中,以SQL Server 2005中包含的數據
- 11. 從SQL Server中的兩個查詢合併數據2005
- 12. 如何在sql server 2005/8中創建沒有聚合函數的Column to Row?
- 13. SQL Server 2005和2008聯合
- 14. 恢復的SQL Server 2014數據庫SQL Server 2005中
- 15. 在SQL Server 2005中壓縮數據庫
- 16. MS SQL Server 2005中 - 將類似數據
- 17. 從MS SQL Server 2005中選擇數據
- 18. 在SQL Server 2005中創建數據庫
- 19. sql server 2005附加數據庫中斷
- 20. SQL Server 2005中
- 21. SQL Server 2005中
- 22. SQL Server 2012動態數據透視表中的聚合
- 23. 指數+ SQL Server 2005中
- 24. SQL Server 2005中RANK函數
- 25. SQL Server 2005的數據透視
- 26. Sql server 2005的數據類型
- 27. SQL Server 2005的日期數據類型
- 28. 如何在SQL Server 2005中恢復SQL SERVER 2008數據庫
- 29. 在SQL Server Management Studio Express中連接到SQL Server 2005數據庫
- 30. 如何在sql server 2005中編寫sql server數據庫圖表?
這不就是一個GROUP BY子句嗎? – leppie 2010-10-18 12:32:40
我的歉意,如果這個問題超出了這個組的規則,我會刪除我的請求。 – 2010-10-18 12:39:36
我並沒有真正明白你的意思,通過壓縮「到每一個可能的多個時間框架,所以讓我們說10分鐘,13,15等等」。你能提供示例數據和期望的結果嗎? – 2010-10-18 12:52:12