2012-06-01 12 views
8

Ho una tabella MySQL contenente i punti (x/y) coordinate dei cingoli. Ogni riga contiene il TrackID, un Timestamp e le Posizioni X e Y per quella traccia in quel determinato momento.SQL: elenco di tutti gli ID che erano attivi durante un determinato intervallo di tempo, filtrate dal loro tempo di avvio

Quello che voglio è un elenco di tutti i TrackID che erano attivi durante un dato intervallo di tempo (tmin ... tmax), ordinati in base al loro orario di inizio, anche se l'ora di inizio è esterna all'intervallo.

Un po 'illustrazione potrebbe aiutare:

Illustration

Per fare un esempio: Traccia 1 è attivo da t11 fino t12, il che significa che ho molti file nella mia tabella con ID = 1 e con il timestamp che vanno da da t11 a t12.

L'output desiderato sarebbe:

TrackID | StartTime 
--------+----------- 
    7 | t71 
    1 | t11 
    2 | t21 
    6 | t61 

Ho provato qualcosa di simile:

SELECT TrackID, MIN(Timestamp) AS StartTime FROM Tracks WHERE Timestamp BETWEEN tmin AND tmax GROUP BY TrackID ORDER BY StartTime; 

Tuttavia, nell'esempio di cui sopra non ottengo i tempi reali di inizio per le tracce 1 e 7 , poiché tutte le righe con data e ora inferiori a tmin non vengono considerate affatto.

Naturalmente ho potuto in una prima fase solo ottenere tutte TrackIDs attivi con

SELECT TrackID FROM Tracks WHERE Timestamp BETWEEN tmin AND tmax GROUP BY TrackID; 

e poi con query separate trovano gli orari di inizio di tutte queste tracce e poi ordinarli nel mio codice dell'applicazione.

ma sono sicuro che ci sia un modo per fare questo con una sola query SQL. La mia tabella contiene milioni di righe, quindi l'efficienza è un problema qui.

+0

Anche l'orario di inizio è fuori e che dire di tempo finale ... Vuoi che lo stesso comportamento ? – DonCallisto

+0

Non mi interessa il tempo di fine in questa applicazione. –

+1

È possibile che l'ora di inizio e l'ora di fine siano entrambi fuori da tmin e tmax senza che vengano visualizzati timestamp tra tmin e tmax? Se è così, allora la tua seconda query avrà un falso negativo in quel caso. – mellamokb

risposta

3

Un modo di pensare a questo proposito è quello di costruire la logica per gestire le vostre quattro casi particolari nel diagramma. Queste due regole dovrebbero essere sufficienti.

  1. tendono> Tmin E
  2. tstart < tmax

Se una di queste due condizioni sono vere, allora la pista dovrebbe essere inclusa.Avrete bisogno di un elenco di brani come nella vostra seconda query con il loro valori minimi e massimi, e quindi eseguire il confronto:

SELECT T.TrackID 
    FROM (SELECT TrackID, MIN(Timestamp) AS StartTime, MAX(Timestamp) AS EndTime 
     FROM Tracks GROUP BY TrackID) T 
WHERE T.EndTime > tmin AND T.StartTime < tmax 
+1

Non ce l'ho nella mia query, ma puoi selezionare "T.StartTime' per ottenere l'ora di inizio e' ORDER BY T.StartTime' per ordinare l'ora di inizio della traccia. – mellamokb

2

ne dite:

SELECT TrackID, MIN(Timestamp) AS StartTime FROM Tracks WHERE EXISTS(
    SELECT * 
    FROM Tracks 
    WHERE Timestamp BETWEEN tmin AND tmax) 
GROUP BY TrackID ORDER BY StartTime; 

Questo è meglio credo:

SELECT SQUERY.TrackID, MIN(SQUERY.Timestamp) AS StartTime FROM (
    SELECT * 
    FROM Tracks 
    WHERE Timestamp BETWEEN tmin AND tmax) AS SQUERY 
GROUP BY SQUERY.TrackID ORDER BY SQUERY.StartTime; 

Ok Sono sicuro che questo è adesso: p

SELECT TrackID, MIN(Timestamp) AS StartTime FROM Tracks WHERE TrackID IN (
    SELECT TrackID 
    FROM Tracks 
    WHERE Timestamp BETWEEN tmin AND tmax) 
GROUP BY TrackID ORDER BY StartTime; 
+0

Sembra promettente. Lo controllerò lunedì! –

+0

Ho appena realizzato che non è giusto. È necessario aggiungere un alias alla tabella nella sottoquery e collegarlo alla tabella principale. Posso farlo in SQL Server ma controllerò prima per vedere se è lo stesso in MySQL – CompanyDroneFromSector7G

+0

Questo è molto simile alla mia soluzione (che ho eliminato perché ho notato una cosa che ho notato anche nella tua risposta). Questo non funzionerà. Pensa a questo: come se t1 (che in un momento di "t" sarà incluso nell'intervallo) abbia anche un inizio e un tempo di fine al di fuori dell'intervallo dato? Sarà elencato e l'ora di inizio potrebbe essere la più piccola! – DonCallisto

-1

Eri a destra traccia con la seconda query, è sufficiente aggiungere una clausola ORDER BY.

SELECT DISTINCT TrackID 
FROM Tracks 
WHERE Timestamp BETWEEN tmin AND tmax 
GROUP BY TrackID 
ORDER BY Timestamp; 
+1

Penso che avrò i tempi di inizio sbagliati per 1 e 7 con questo approccio. Ma controllerò lunedì. –

+0

Questo ti darà quello che hai chiesto, "Quello che voglio è un elenco di tutti i TrackID che erano attivi durante un dato intervallo di tempo (tmin ... tmax), ordinati in base al loro orario di inizio, anche se quell'ora di inizio è al di fuori l'intervallo. " SELECT/WHERE restituisce l'elenco di TrackID con timestamp associati tra l'inizio e la fine che vengono quindi ordinati dal Timestamp minimo. – Sean

4

Date un'occhiata al tua foto - tutte le gamme che si desidera avere il tempo maggiore di min fine e inizio tempo inferiore max.

+0

@mellamokb Ho corretto l'errore - ho dimenticato di scrivere 'e ora di inizio' meno di ... –

+0

D'accordo, ti ho dato +1 :) – mellamokb

+0

@mellamokb Non ha senso scrivere una query ora che hai presentato la tua: -) –

Problemi correlati