2017-10-06 5 views
3

Est-il possible d'écrire une requête SQL qui regroupe les lignes en fonction de la différence d'une valeur de colonne datetime par rapport à la valeur d'une ligne adjacente?Est-il possible de grouper les lignes les unes par les autres dans T-SQL?

Permettez-moi de donner un exemple ... J'ai une requête SQL quelque chose comme ceci:

SELECT 
    Id, 
    StartTime, 
    EndTime, 
    datediff(second, max(StartTime), EndTime)) as Duration 
FROM Timings 
ORDER BY StartTime 

qui renvoie les résultats quelque chose comme ceci:

| ID | StartTime   | EndTime    | Duration 
| 1 | 2017-10-06 10:59:48 | 2017-10-06 10:59:58 | 10 
| 2 | 2017-10-06 11:00:02 | 2017-10-06 11:00:06 | 4 
| 3 | 2017-10-06 11:00:15 | 2017-10-06 11:00:22 | 7 
| 4 | 2017-10-06 11:00:30 | 2017-10-06 11:00:39 | 9 
| 5 | 2017-10-06 15:34:31 | 2017-10-06 15:34:45 | 14 
| 6 | 2017-10-06 15:34:48 | 2017-10-06 15:34:56 | 8 
| 7 | 2017-10-06 15:34:52 | 2017-10-06 15:34:59 | 7 

L'important est que les horaires sont en deux lots, les quatre premiers ont tous été faits vers 11h, et les deux autres vers 15h et 15h.

Je souhaite obtenir des détails sur l'heure de début/fin de chaque série de minutages, la durée moyenne et le nombre de minutages dans un groupe. Pour ce faire, j'ai besoin d'un moyen de grouper les timings par lots, où un groupe est défini comme le groupe de timings avec moins de 30 secondes entre la fin de l'un et le début de l'autre, quand il est ordonné par l'heure de début. C'est possible?

Quelques notes complémentaires sur la situation réelle ...

  • La seule distinction vraiment caractéristique d'un lot est que l'écart entre la fin d'un temps et le début de la prochaine sera beaucoup plus grand. Codage dur d'une limite de temps fixe serait OK.
  • Comme dans cet exemple, il peut y avoir plusieurs lots par jour, donc le regroupement par date est terminé.
  • En réalité, les lots peuvent durer de quelques minutes à plusieurs heures, ne contenant que quelques instants, ou plusieurs milliers. Il n'y a pas d'heures fixes pour les lots.
  • Notez les horaires sur les lignes 6 & 7. Des synchronisations multiples se produisent en parallèle se chevauchant, la distinction d'un grand écart entre la fin de l'un et le début de la suivante reste cependant comme la manière d'identifier les lots .

Répondre

3

Dans SQL Server 2012+:

Utilisation de la fonction de fenêtre lag() dans un common table expression pour obtenir le datediff() de la ligne courante starttime par rapport à la valeur précédente de ligne pour endtime, puis sum() over() avec l'agrégation conditionnelle (comparision à la valeur codée en dur) pour générer le batch:

;with cte as (
select * 
    , datediff(second,lag(endtime) over (order by starttime),starttime) as prev_dat 
from timings 
) 
select id, starttime, endtime, duration 
    , sum(case when coalesce(prev_dat,31)>30 then 1 else 0 end) over (
    order by starttime 
    ) as batch 
from cte 

rextester demo: http://rextester.com/OVNF90739

retours:

+----+---------------------+---------------------+----------+-------+ 
| id |  starttime  |  endtime  | duration | batch | 
+----+---------------------+---------------------+----------+-------+ 
| 1 | 2017-10-06 10:59:48 | 2017-10-06 10:59:58 |  10 |  1 | 
| 2 | 2017-10-06 11:00:02 | 2017-10-06 11:00:06 |  4 |  1 | 
| 3 | 2017-10-06 11:00:15 | 2017-10-06 11:00:22 |  7 |  1 | 
| 4 | 2017-10-06 11:00:30 | 2017-10-06 11:00:39 |  9 |  1 | 
| 5 | 2017-10-06 15:34:31 | 2017-10-06 15:34:45 |  14 |  2 | 
| 6 | 2017-10-06 15:34:48 | 2017-10-06 15:34:56 |  8 |  2 | 
| 7 | 2017-10-06 15:34:52 | 2017-10-06 15:34:59 |  7 |  2 | 
+----+---------------------+---------------------+----------+-------+ 
+0

C'est brillant. Travaillé parfaitement. Je vous remercie. –

+0

@SimonPStevens Joyeux d'aider! – SqlZim

0

Vous pouvez grouper les pièces datetime

group by DATEPART(StartTime, yyyy) + DATEPART(StartTime, MM) + DATEPART(StartTime, DD) 

Vous souhaitez également vous devez modifier sélectionnez pour correspondre

+0

Merci, mais cela ne fonctionne pas car il peut y avoir plusieurs lots le même jour, ou les lots peuvent s'étaler sur plusieurs heures, donc il n'y a pas de combinaison de partie date/heure qui définira toujours un lot de façon unique. –