J'ai besoin d'une requête pour le serveur SQl 2005 (SQL Server Management Studio Express). Les données sont stockées sous la forme d'une période de 1 minute (1 minute par ligne), pour chaque colonne de table: ID, Symbole, DateHeure, Ouvert, Haut, Bas, Fermé, Volume. J'ai besoin de convertir (compresser) à tous les temps possibles, disons 10 minutes, 13, 15, et ainsi de suite. Donnez tous les détails si quelqu'un pouvait vous aider. Merci AlbertoAgrégation de données dans SQL Server 2005
Répondre
;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
Ou une autre approche qui pourrait valoir la peine d'être testée pour voir si elle est plus rapide.
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
Merci Martin, mais j'ai une erreur: peut-être que je peux vous fournir des exemples de données xls à partir de ma base de données SQL, je peux imaginer qu'il est très difficile de coder correctement cette requête sans données. Puis-je joindre un fichier ici? Sinon, acepsut est mon pseudo Skype ainsi que mon compte gmail.com –
Quelle erreur obtenez-vous? (Si vous voulez mettre des données quelque part peut-être Google feuilles de calcul serait un bon endroit?) –
@Alberto - Ceci est mis à jour suite à des commentaires sous la réponse de smirkingman. –
Alberto, il semble que vous ayez besoin d'une clause "Group By" dans les instructions SQL (comme Leppie l'a indiqué). Donc, vous devriez mieux le chercher.
Vous devez d'abord filtrer les lignes soumises à l'agrégation en utilisant les dates et heures de début et de fin, puis les regrouper selon la clause mentionnée.
Voici la première link lorsque je recherche des mots-clés "sql group by" via Google.
Pas simple "Regrouper par" - Les valeurs Open et Close doivent être prises pour la première et la dernière ligne du groupe. Ou du moins est-ce aussi pour les données Forex :)
Oui, c'est correct, ce n'est pas un groupe simple . –
Est-ce plus joli avec un proc stocké pour extraire MIN (datetime) d'abord, mais voici un croquis:
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
La clause obtient une liste des intervalles de 15 minutes, arrondi vers le bas, dans votre ensemble de données (supposons rien avant 2000). Ensuite, utilisez ces intervalles pour grouper par intervalle de 14:59. Pour le volume, vous devrez décider si vous voulez la moyenne ou le total.
La syntaxe peut être un peu large, mais vous devriez avoir l'idée.
EDIT: MIN ajusté (ouvert), MIN (proche) pour sélectionner PREMIER et DERNIER. En réalité, cela ne changera pas beaucoup, car le concept d'ouverture et de fermeture dépend de la différence de temps entre l'échange d'où provient la citation et l'horloge de l'ordinateur qui collecte les données.
De plus, à moins que l'OP n'ait le privilège d'un flux en temps réel de tous les centraux, toutes les citations sont quand même retardées de 20 minutes.
EDIT (2): Tout à fait prenom et sont reports de mes jours IBM> ;-)
Solution sélectionne maintenant première et dernière citations au cours de l'intervalle à l'aide TOP avec ASC/DESC.
Pourquoi avez-vous' MIN (ouvert) 'et' MIN (fermer) ' ? Le PO a besoin du prix «ouvert» lié au premier enregistrement par segment et du prix «proche» du dernier enregistrement par segment. –
Paresse. Ses données proviennent d'un flux de prix. Ouvrir et fermer ne peut pas changer pendant la journée, ils sont le cours de l'action première chose ce matin et la dernière chose la nuit dernière. – smirkingman
Cela a effectivement du sens, mais ce n'est pas ainsi que l'OP le définit dans les commentaires. "Fermer (dernier prix dans cet intervalle de temps)" @Alberto - Pouvez-vous clarifier? –
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
;
Merci Nikola, j'ai quelques erreurs 1) Message 102 niveau 15 rang 13 Sintaxe incorrecte près de ',' 2) Message 139 niveau 15 row impossibile pour allouer une valeur prédéfinie à une variable locale 3) Message 137 level 15 row 30 Déclarer la valeur scalaire "@nRowsPerGroup". –
Cela ne fonctionnera pas si l'enregistrement pour 09:00:00 est manquant (voir les commentaires précédents) – smirkingman
Cela fonctionne. Retirez simplement l'insertion pour le 09:00:00 et essayez. En fait, vous pouvez supprimer n'importe quel nombre de lignes que vous voulez. – Niikola
- 1. Comptage de données SQL Server 2005
- 2. Pagination de données: SQL Server 2005 + SL3
- 3. Sql Server 2005 Types de données
- 4. Agrégation de chaînes dans SSRS 2005
- 5. to_date dans SQL Server 2005
- 6. SQL Server 2005 "Pin" données en mémoire
- 7. Supprimer de grandes quantités de données dans SQL Server 2005
- 8. SQL SERVER 2005
- 9. Requête SQL SQL Server 2005
- 10. Requête SQL Server 2005
- 11. Type de données SQL Server 2005 à SQL 2000
- 12. Vues SQL Server 2005
- 13. Union dans SQL Server 2005
- 14. SQL Server 2005: détection de cycles dans des données hiérarchiques
- 15. Modification des types de données dans SQL Server 2005
- 16. Création d'une base de données dans SQL Server 2005
- 17. trigger dans sql server 2005
- 18. sélectionnez dans SQL Server 2005
- 19. Insertion de DateTime dans Sql Server 2005
- 20. Importation de la base de données Sql Server 2005 dans Sql Server express 2008
- 21. transaction SQL Server 2005
- 22. SQL Server 2005 sp_send_dbmail
- 23. Agrégation de chaînes groupées/LISTAGG pour SQL Server
- 24. Sql Server 2005 AutoCompletion
- 25. SQL Server 2005 xp_cmdshell
- 26. SQL Server 2005
- 27. SQL Server 2005 - droits utilisateur
- 28. SQL Server 2005 Replication
- 29. Rétrogradation de SQL Server 2008 vers SQL Server 2005
- 30. SQL Server 2005 - requêtes prioritaires
N'est-ce pas une clause GROUP BY? – leppie
Mes excuses, si cette question va au-delà des règles de ce groupe, je vais supprimer ma demande. –
Je ne comprends pas vraiment ce que vous voulez dire en compressant "à toutes les périodes possibles, disons 10 minutes, 13, 15, et ainsi de suite". Pouvez-vous fournir des exemples de données et le résultat souhaité? –