2016-04-27 11 views
-1

Ich habe Daten im folgenden Format und möchte es im zweiten Format ausgeben. Ich habe versucht, ein Self-Join auf die Daten und gruppieren nach ID, Zeit und Ereignis, aber nichts, was ich versucht habe, scheint richtig zu funktionieren.Abfrage, um maximale Zeit von einer Gruppe für jede Gruppe zu erhalten

Die Zeit bei EV-2 ist die Startzeit und die Zeit bei EV-5 ist die Endzeit. EV-5-Zeit kann als Endzeit für jedes EV-2-EV-5-Ereignis geschrieben werden.

Danke für jede Anleitung mit dieser Angelegenheit.

ID TIME      EVENT 
1 2016-03-21 12:30:00.000  EV-1  
1 2016-03-21 12:30:30.000  EV-2 
1 2016-03-21 12:33:00.000  EV-3 
1 2016-03-21 12:33:00.000  EV-4 
1 2016-03-21 12:33:45.000  EV-5 
1 2016-03-21 12:33:50.000  EV-1  
1 2016-03-21 12:33:55.000  EV-2 
1 2016-03-21 12:35:15.000  EV-3 
1 2016-03-21 12:35:15.000  EV-4 
1 2016-03-21 12:40:20.000  EV-5 
2 2016-03-21 12:40:50.000  EV-1  
2 2016-03-21 12:41:25.000  EV-2 
2 2016-03-21 12:41:25.000  EV-3 
2 2016-03-21 12:42:13.000  EV-4 
2 2016-03-21 12:47:35.000  EV-5 

Output 
ID TIME(startTime)    EVENT endTime 
1 2016-03-21 12:30:00.000  EV-1  
1 2016-03-21 12:30:30.000  EV-2 2016-03-21 12:33:45.000 
1 2016-03-21 12:33:00.000  EV-3 2016-03-21 12:33:45.000 
1 2016-03-21 12:33:00.000  EV-4 2016-03-21 12:33:45.000 
1 2016-03-21 12:33:45.000  EV-5 2016-03-21 12:33:45.000 
1 2016-03-21 12:33:50.000  EV-1  
1 2016-03-21 12:33:55.000  EV-2 2016-03-21 12:40:20.000 
1 2016-03-21 12:35:15.000  EV-3 2016-03-21 12:40:20.000 
1 2016-03-21 12:35:15.000  EV-4 2016-03-21 12:40:20.000 
1 2016-03-21 12:40:20.000  EV-5 2016-03-21 12:40:20.000 
2 2016-03-21 12:40:50.000  EV-1  
2 2016-03-21 12:41:25.000  EV-2 2016-03-21 12:47:35.000 
2 2016-03-21 12:41:25.000  EV-3 2016-03-21 12:47:35.000 
2 2016-03-21 12:42:13.000  EV-4 2016-03-21 12:47:35.000 
2 2016-03-21 12:47:35.000  EV-5 2016-03-21 12:47:35.000 

Was ich versucht habe:

select d.ID, d.TIME, d.EVENT, max(dd.TIME) endTime 
from dataTable d 
    inner join dataTable dd on d.ID = dd.ID and d.EVENT = dd.EVENT and d.TIME < dd.TIME 
group by d.ID, d.TIME, d.EVENT 
+3

Was Ihr DBMS ist? – Siyual

+3

Können Sie Ihre versuchte Abfrage anzeigen? –

+0

Select d.ID, d.TIME, d.EVENT, max (dd.TIME) endTime von datatable d Exklusionsverknüpfung datatable dd auf d.ID dd.ID = und d.EVENT dd.EVENT = und d.TIME

Antwort

0

Einfache Lösung, verwenden Sie eine korrelierte Unter wählen Sie die kleinste EV-5 Mal größer oder gleich der aktuellen Zeile Zeit zurückzukehren. (. Haben Sie einen case Ausdruck dies für alle Veranstaltungen zu tun, sondern EV-1)

select t1.*, case when t1.event <> 'EV-1' then (select min(t2.TIME) from dataTable t2 
               where t2.event = 'EV-5' 
                and t2.TIME >= t1.time) 
      end as endTime 
from dataTable t1 

Alternativ, wenn id verwendet werden kann, ein selbst tun (links) anschließen:

select t1.*, case when t1.event <> 'EV-1' then t2.TIME 
      end as endTime 
from dataTable t1 
    left join dataTable t2 on t1.id = t2.id and t2.event = 'EV-5' 

(left join zu Rückkehr auch ids ohne EV-5, falls erforderlich)

+0

Es scheint, dass die Ereignisse durch ID verbunden sind ... – dotjoe

+0

@dotjoe, nette Beobachtung. Verpasste dieses Detail! – jarlh

0

@ Logik des jarhl für DBMSes Windowed Aggregatfunktionen wie SQL Server unterstützt 2014.

SELECT t.*, 
    CASE 
    WHEN EVENT <> 'EV-1' 
    THEN MIN(CASE WHEN EVENT = 'EV-5' THEN TIME end) 
      OVER (PARTITION BY ID -- maybe not needed 
       ORDER BY TIME 
       ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) 
    END AA endTime 
FROM tablename AS t1 
+0

Vielen Dank! Deine Lösung hat sehr gut funktioniert, genau das, wonach ich gesucht habe. –

0

Ihre ID-Spalte zu einer tatsächlichen ID korrigieren, versuchen

IF (SELECT OBJECT_ID('tempdb..#Events')) IS NOT NULL 
BEGIN 
    DROP TABLE #Events 
END 

CREATE TABLE #Events (ID INT,EventTime datetime, eventName varchar(4)) 
INSERT INTO #Events 
VALUES   
(1, '2016-03-21 12:30:00.000','EV-1'), 
(1, '2016-03-21 12:30:30.000','EV-2'), 
(1, '2016-03-21 12:33:00.000','EV-3'), 
(1, '2016-03-21 12:33:00.000','EV-4'), 
(1, '2016-03-21 12:33:45.000','EV-5'), 
(2, '2016-03-21 12:33:50.000','EV-1'), 
(2, '2016-03-21 12:33:55.000','EV-2'), 
(2, '2016-03-21 12:35:15.000','EV-3'), 
(2, '2016-03-21 12:35:15.000','EV-4'), 
(2, '2016-03-21 12:40:20.000','EV-5'), 
(3, '2016-03-21 12:40:50.000','EV-1'), 
(3, '2016-03-21 12:41:25.000','EV-2'), 
(3, '2016-03-21 12:41:25.000','EV-3'), 
(3, '2016-03-21 12:42:13.000','EV-4'), 
(3, '2016-03-21 12:47:35.000','EV-5') 
; 
WITH cteEvent AS 
(
    SELECT ID, EventTime AS startTime,en.endTime 
    FROM #Events e 
    CROSS APPLY (
        SELECT EventName,EventTime AS endTime 
        FROM #Events e2 
        WHERE e2.ID = e.id AND CAST(RIGHT(e2.eventname,1) AS INT) = 5) as en 
    WHERE e.EventName = 'EV-1' 
) 
SELECT c.id,eventName,startTime, 
    CASE 
     WHEN eventName = 'EV-1' 
     THEN NULL 
     ELSE endTime 
    END AS endTime 
FROM cteEvent c 
LEFT JOIN #Events e ON c.id = e.id 
Verwandte Themen