2010-03-05 17 views
5

Ho una tabella in cui ho datetimes associato ad un ID:Selezionare TimeRange più lunga comune

┌────────────────┬──────────────────────┐ 
│ location_id | datetime    | 
├────────────────┼──────────────────────┤ 
│ 200333   | 2008-01-01 00:00:00 | 
│ 200333   | 2008-01-01 01:00:00 | 
│ 200333   | 2008-01-01 02:00:00 | 
| ...   | ...     | 
│ 200333   | 2009-10-23 21:00:00 | 
│ 200333   | 2009-10-23 22:00:00 | 
│ 200333   | 2009-10-23 23:00:00 | 
│ 200768   | 2008-06-01 00:00:00 | 
│ 200768   | 2008-06-01 01:00:00 | 
│ 200768   | 2008-06-01 02:00:00 | 
| ...   | ...     | 
│ 200768   | 2009-12-31 00:00:00 | 
│ 200768   | 2009-12-31 00:00:00 | 
│ 200768   | 2009-12-31 00:00:00 | 
└────────────────┴──────────────────────┘ 

Quale sarebbe il modo per selezionare il periodo di tempo più lungo questi due sovrapposti location_id 's quota? In questo caso, l'output desiderato sarebbe:

┌──────────────────────┬──────────────────────┐ 
│ start    | end     | 
├──────────────────────┼──────────────────────┤ 
│ 2008-06-01 00:00:00 | 2009-10-23 23:00:00 | 
└──────────────────────┴──────────────────────┘ 

posso facilmente ottenere il più lungo periodo disponibile utilizzando MIN() e MAX() ma come potrei fare per la selezione del massimo di datetimes minima e minimo di datetimes massimo?

Oh, e questa tabella contiene 19 000 000 righe, in modo da punti bonus per i suggerimenti che corrono veloci :)

+1

C'è un errore di battitura nel vostro output finale desiderato: 2009-10-23 23:00:00 invece di 2008-10-23 23:00:00 ? – Patrick

+1

@Patrick, sì, un errore di battitura. –

risposta

2

si può provare qualcosa

SELECT MAX(MinDates) MaximumMinDate, 
     MIN(MaxDates) MinimumMaxDate 
FROM (
      SELECT location_ID, 
        MIN([datetime]) MinDates, 
        MAX([datetime]) MaxDates 
      FROM Table 
      WHERE location_ID IN (200333, 200768) 
      GROUP BY location_ID 
     ) sub 

E poi basta sostituire gli ID con quello che vi serve .

+0

Questo funziona bene e non riesco a vedere un modo in cui questo potrebbe essere più ottimizzato. Avevo un po 'paura di usare una sottoquery, temendo che potesse uccidere la mia performance, ma la sottoquery viene eseguita separatamente quanto tutta questa query, quindi non ci sono problemi. Grazie! –

0

Spero che questo funziona per voi:

SELECT l1.maxtime, l2.mintime FROM 
(SELECT location_id, min(datetime), max(datetime) 
FROM table 
GROUP BY location_id 
) as l1(id, mintime, maxtime) 
, 
(SELECT location_id, min(datetime), max(datetime) 
FROM table 
GROUP BY location_id 
) as l2(id, mintime, maxtime) 
WHERE 
l1.id <> l2.id 
HAVING max(l1.maxtime-l2.mintime); 
Problemi correlati