2011-01-02 4 views
1

je l'exemple suivant pour lequel je voudrais calculer les totaux à chaque fois disponible:calcul sommaire pour différents temps

timestamp device value 
2010-12-30 00:00 1 5 
2010-12-30 00:05 1 5 
2010-12-30 00:05 2 10 
2010-12-30 00:13 1 23 
2010-12-30 00:16 3 11 
2010-12-30 00:30 1 22 
2010-12-30 00:40 2 55 
2010-12-30 00:40 3 12 
2010-12-30 00:45 2 12 
2010-12-30 10:00 3 33 

A la fin le résultat devrait ressembler à ceci:

timestamp Total 
2010-12-30 00:00 5 
2010-12-30 00:05 5 
2010-12-30 00:05 15 
2010-12-30 00:13 33 
2010-12-30 00:16 44 
2010-12-30 00:30 43 
2010-12-30 00:40 88 
2010-12-30 00:40 89 
2010-12-30 00:45 46 
2010-12-30 10:00 67 

L'idée est que pour chaque horodatage, j'ai besoin d'obtenir la dernière valeur pour chaque appareil, puis SUM sur les valeurs.

Par exemple:

Pour timestamp 2010-12-30 00:13 je avais besoin de prendre les entrées suivantes et SUM:

2010-12-30 00:05 2 10 
2010-12-30 00:13 1 23 

Le total serait alors 26. Pour timestamp 2010-12-30 10:00 je dois prendre les lignes suivantes:

2010-12-30 00:30 1 22 
2010-12-30 00:45 2 12 
2010-12-30 10:00 3 33 

Ce qui donne 67 comme le total. Mon idée était de créer une requête qui sélectionnerait les dernières valeurs pour chaque périphérique pour chaque horodatage, mais je suis déjà bloqué sur la sélection des dernières valeurs pour chaque périphérique pour un horodatage spécifique, alors je vous demanderais soutien.

+2

Si vous publiez code ou XML, ** ** S'il vous plaît mettre en évidence les lignes dans l'éditeur de texte et cliquez sur le " code samples "bouton ({}) sur la barre d'outils de l'éditeur pour bien le mettre en forme et la syntaxe le mettre en évidence! –

+0

Cette première somme - pour l'horodatage 2010-12-30 00:13 - ne devrait-elle pas être 33 ?? Vous voulez dire résumer les 10 et 23 comme valeurs, non? –

+0

Combien de lignes y a-t-il dans votre base de données? La performance est-elle un problème? –

Répondre

1

Voici une approche. La requête sélectionne toutes les lignes de la table, puis utilise outer apply pour résumer la dernière valeur par périphérique. La requête not exists filtre les lignes qui ne sont pas la dernière ligne de ce périphérique.

select t1.timestamp 
,  last_rows_per_device.Total 
from @t t1 
outer apply 
     (
     select sum(t2.value) as Total 
     from @t t2 
     where (
        t2.timestamp < t1.timestamp 
        or (t2.timestamp = t1.timestamp and t2.device <= t1.device) 
       ) 
       and not exists 
       (
        select * 
        from @t t3 
        where t3.device = t2.device 
          and t2.timestamp < t3.timestamp 
          and t3.timestamp <= t1.timestamp 
       ) 
     ) last_rows_per_device 
order by 
     t1.timestamp 
,  t1.device 

La requête suppose que (timestamp, device) est unique, et il commande les lignes avec le même horodatage par identifiant de dispositif, le premier dispositif le plus bas.

Cela correspond à votre exemple de sortie:

timestamp    Total 
2010-12-30 00:00  5 
2010-12-30 00:05  5 
2010-12-30 00:05  15 
2010-12-30 00:13  33 
2010-12-30 00:16  44 
2010-12-30 00:30  43 
2010-12-30 00:40  77 
2010-12-30 00:40  89 
2010-12-30 00:45  46 
2010-12-30 10:00  67 

données Source:

declare @t table (timestamp datetime, device int, value int) 
insert @t (timestamp, device, value) 
      select '2010-12-30 00:00', 1, 5 
union all select '2010-12-30 00:05', 1, 5 
union all select '2010-12-30 00:05', 2, 10 
union all select '2010-12-30 00:13', 1, 23 
union all select '2010-12-30 00:16', 3, 11 
union all select '2010-12-30 00:30', 1, 22 
union all select '2010-12-30 00:40', 2, 55 
union all select '2010-12-30 00:40', 3, 12 
union all select '2010-12-30 00:45', 2, 12 
union all select '2010-12-30 10:00', 3, 33 
+0

Celui-ci fonctionne. C'est assez lent, mais merci quand même. – Mark