2017-10-06 5 views
1

J'ai une table ressemble à cecicomment calculer le temps dans SQL

ID    DTTM 
123456789 2017-10-05 08:00:00.000 
123456789 2017-10-05 08:05:00.000 
123456789 2017-10-05 08:07:00.000 
123456789 2017-10-05 08:15:00.000 
123456789 2017-10-05 08:25:00.000 
123456789 2017-10-05 09:00:00.000 
123456789 2017-10-05 09:01:00.000 
123456789 2017-10-05 09:02:00.000 
123456789 2017-10-05 09:03:00.000 
123456789 2017-10-05 11:00:00.000 

Je dois créer un drapeau basé sur l'intervalle de temps (date pas d'importance) Il doit être intervalle de 15 minutes pour pour mettre le drapeau à 1 Donc dans ce cas, les lignes 1,4,6,10 seront drapeau et le total sera de 4 pour cet ID Chaque fois que le interval >= 15 minutes il va recommencer jusqu'à la prochaine J'ai essayé quelque chose comme ça; Avec myLead AS

(
Select  top 100 percent 
      ID, 
      DTTM,     
      LEAD(DTTM,1) over (partition by ID order by DTTM) as NextDTTM 
From  Example 
Order by ID 
), myCount 
AS 
(
Select  Top 100 percent 
      ID, 
      DTTM, 
      NextDTTM, 
      DateDiff("MINUTE",DTTM,NextDTTM) as Interval 
from  myLead 
) 
Select  ID, 
      DTTM, 
      NextDTTM, 
      Interval, 
      Case When Interval >= 15 then 1 else 0 END as CountFlag 
From  myCount 
Where  Interval is not NULL 
Order by ID 

Mais il ne fonctionne comme prévu? comment puis-je résoudre cela.

Merci, Oded Dror

Répondre

0

Je ne sais pas comment vous avez besoin du drapeau ressemble, mais en utilisant SQL Server 2012 ils sont deux parties difficiles. Tout d'abord, pour obtenir la différence de temps entre autre et rangée précédente:

DECLARE @DataSource TABLE 
(
    [ID] BIGINT 
    ,[DTTM] DATETIME2 
); 

INSERT INTO @DataSource ([ID], [DTTM]) 
VALUES (123456789, '2017-10-05 08:00:00.000') 
     ,(123456789, '2017-10-05 08:05:00.000') 
     ,(123456789, '2017-10-05 08:07:00.000') 
     ,(123456789, '2017-10-05 08:15:00.000') 
     ,(123456789, '2017-10-05 08:25:00.000') 
     ,(123456789, '2017-10-05 09:00:00.000') 
     ,(123456789, '2017-10-05 09:01:00.000') 
     ,(123456789, '2017-10-05 09:02:00.000') 
     ,(123456789, '2017-10-05 09:03:00.000') 
     ,(123456789, '2017-10-05 11:00:00.000'); 

SELECT * 
     ,DATEDIFF(MINUTE,CONVERT(TIME, [DTTM]),LEAD(CONVERT(TIME, [DTTM]), 1, NULL) OVER (PARTITION BY [ID] ORDER BY [DTTM])) AS [Minutes] 
FROM @DataSource 
ORDER BY [DTTM]; 

enter image description here

, nous avons alors besoin sum les minutes de la mendicité de plus d'intervalle à la ligne courante et les diviser à 15:

WITH DataSource AS 
(
    SELECT * 
      ,DATEDIFF(MINUTE,LAG(CONVERT(TIME, [DTTM]), 1, NULL) OVER (PARTITION BY [ID] ORDER BY [DTTM]), CONVERT(TIME, [DTTM])) AS [Minutes] 
    FROM @DataSource 
) 
SELECT * 
     ,SUM(ISNULL([Minutes], 0)) OVER (PARTITION BY [ID] ORDER BY [DTTM] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)/15 AS [MinutesRank] 
FROM DataSource; 

enter image description here

Ayant cela, vous pouvez faire ce que vous nE ne ed, comme nous avons maintenant combien de minutes nous avons jusqu'à chaque ligne. Par exemple:

WITH DataSource AS 
(
    SELECT * 
      ,DATEDIFF(MINUTE,LAG(CONVERT(TIME, [DTTM]), 1, NULL) OVER (PARTITION BY [ID] ORDER BY [DTTM]), CONVERT(TIME, [DTTM])) AS [Minutes] 
    FROM @DataSource 
) 
, DataSourceMinutesTotal AS 
(
    SELECT * 
      ,SUM(ISNULL([Minutes], 0)) OVER (PARTITION BY [ID] ORDER BY [DTTM] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)/15 AS [MinutesRank] 
    FROM DataSource 
) 
SELECT [ID], [DTTM] 
     ,DENSE_RANK() OVER (PARTITION BY [ID] ORDER BY ISNULL([MinutesRank], 0)) AS [IntervalID] 
FROM DataSourceMinutesTotal 
ORDER BY [DTTM]; 

enter image description here

+0

Gotqn, Nous vous remercions de votre aide, le problème a déjà été résolu. Cette solution ne donnera pas le résultat que je cherchais. –

0

Si vous utilisez MySQL alors vous pouvez essayer d'utiliser TIMEDIFF(param1, param2) * param1 et param2 peut être temps ou datetimes valeurs

+0

Merci de me contacter, le problème à semelle. Votre approche n'a pas résolu le problème. –