2013-02-08 18 views
5

Desidero raggruppare i dati in una tabella in base all'intervallo di tempo. La tabella mantiene le informazioni sugli ordini che includono userid, nome oggetto, modello, quantità, data di attività, ecc. Ora desidero raggruppare questi dati per intervalli di tempo. L'intervallo di tempo potrebbe essere qualsiasi cosa come 5 min, 10 min, 15, ecc. Inoltre, la query dovrebbe restituire solo quegli utenti (tutti i dati della colonna) che hanno effettuato ordini più di una volta all'interno dell'intervallo di 5 minuti. È possibile ottenere questo risultato in una query SQL? Io uso Oracle.Raggruppamento dati per intervallo di tempo

Grazie

Modifica:

dati campione

**userid item name model  quantity order date** 
abc calculator cdm83ss 1  02-FEB-2013 09:20:13  
abc alarm clock actp001 1  02-FEB-2013 09:26:22 
yyy iPhone  iP4 1  02-FEB-2013 09:28:14 
abc alarm clock actz321 2  02-FEB-2013 09:30:00 
zzz backpack  bp344tk 1  04-FEB-2013 13:15:00 
zzz backpack  bp234zz 2  04-FEB-2013 13:19:32 
zzz camera  cm234 1  04-FEB-2013 13:20:22 
ttt tv  fs45yup 1  04-FEB-2013 13:28:19 

mi aspetto di ottenere:

**userid item name model  quantity order date** 
abc   calculator cdm83ss 1  02-FEB-2013 09:20:13  
abc   alarm clock actp001 1  02-FEB-2013 09:26:22 
abc   alarm clock actz321 2  02-FEB-2013 09:30:00 
zzz   backpack  bp344tk 1  04-FEB-2013 13:15:00 
zzz   backpack  bp234zz 2  04-FEB-2013 13:19:32 
zzz   camera  cm234 1  04-FEB-2013 13:20:22 
+2

Sì ... puoi fornirci di partenza del campione dati, risultati desiderati e i tuoi sforzi fino ad ora?Oh, sono questi intervalli 'rigidi' (a: 05,: 10,: 15,: 20,: 25, ecc.), O 'hanno fatto due vendite a meno di 5 minuti di distanza' tipo di cose? –

+0

@Mike - È impossibile aiutarti veramente se non fornisci dati e strutture di esempio. Inoltre, sarai sottovalutato per tali domande presumendo che possiamo leggere la tua mente e creare strutture e campionare dati per te. – Art

+0

@ Clockwork-Muse/@ Art, ho aggiornato la mia domanda con alcuni dati di esempio. La risposta di Gordan Linoff è vicina a quello che sto cercando. Tuttavia, esclude alcuni dati. Ad esempio, nei miei dati di esempio, la persona "zzz" aveva tutte le sue transazioni entro 10 minuti (da 13: 15: 00-13: 20: 22). L'intervallo di tempo a partire dall'approccio di mezzanotte esclude la transazione avvenuta alle 13:20:22 poiché cade nell'intervallo dei successivi 10 minuti. – Mike

risposta

7

Sì. Presumibilmente, vuoi vedere il risultato anche come valore datetime. Ciò richiede alcune operazioni aritmetiche datetime. In pratica, ottenendo il numero di minuti da mezzanotte, dividendo per il numero di minuti e quindi moltiplicando di nuovo (per arrotondare per difetto). Poi aggiungendo indietro nel tempo a mezzanotte:

select t.* 
from (select t.*, 
      count(*) over (partition by userid, interval) as CntInInterval 
     from (select trunc(orderdate)+ 
        (floor(((orderdate - trunc(orderdate))*24*60)/10)*10)/(24*60) as interval, t.* 
      from t 
      ) t 
    ) t 
where cntInInterval > 1 

Per raggruppare da intervalli di tempo, si può usare:

 select interval, count(*) 
     from (select trunc(orderdate)+floor(((orderdate - trunc(orderdate))*24*60)/10)*10 as interval, t.* 
      from t 
      ) t 
     group by interval 

In queste query, "10" sta per qualsiasi numero di minuti. Si noti che questi sono calcolati da mezzanotte, quindi un valore come 17 inizia sempre con i primi 17 minuti del giorno.

La definizione di intervallo è un'espressione aritmetica su date.

trunc (OrderDate) + piano (((DataOrdine - trunc (OrderDate)) * 24 * 60)/10) * 10 come intervallo,

La prima parte, trunc(orderdate), è sintassi Oracle per rimuovere il tempo parte di una data. Questo sposta la data a mezzanotte all'inizio della giornata.

L'espressione orderdate - trunc(orderdate) calcola il numero di giorni da mezzanotte - questa è una parte frazionaria di un giorno. Quindi, 0,25 sarebbero le 6:00. Lo *24*60 lo converte in minuti. Quindi, 0,25 diventa 0,25 * 60 * 24 = 360 - il numero di minuti dalla mezzanotte.

Quindi l'espressione floor(x/y)*y semplicemente "tronca" qualsiasi valore sul multiplo inferiore di y. Quindi, floor(118/10) è 11 e 11 * 10 è 110. In altre parole, questo mapperà tutti i valori tra a * y e (a + 1) * y (fino a non includere) allo stesso valore, a * y.

consideri l'espressione, in pratica, il 6:08 il 2013-01-01:

`trunc(orderdate)` moves the date to midnight on 2013-01-01. 
`orderdate - trunc(orderdate)` creates a number like 0.25. 
`((orderdate - trunc(orderdate))*24*60)` produces the value 368 
`floor(((orderdate - trunc(orderdate))*24*60)/10)*10` produces 360 
`floor(((orderdate - trunc(orderdate))*24*60)/10)*10*(1/24*60)` produces 0.25 

E quando questo viene aggiunto al minight, il tempo si trasforma in 06:00 di nuovo.

+0

Grazie mille. Questo è quello che volevo. Tuttavia ho notato che questo esclude alcuni dati in scenari come questo, i tempi ordinati per un utente: 09:32:12, 09:37:34, 09:40:21. In questo caso, mostra solo 09:32:12 e 09:37:34, non 09:40:21. Capisco perché non sta contando questa data/ora, perché cade nell'intervallo successivo di 10 minuti (anche se tutte le transazioni di questa persona hanno richiesto 10 minuti). Sarebbe bello poter contare anche questa data/ora (dal momento che tutte le transazioni di questa persona sono avvenute in 10 minuti). – Mike

+0

Gordon, La prego di aiutarmi a capire questa domanda "select trunc (sysdate) + floor (((sysdate - trunc (sysdate)) * 24 * 60)/5) * 5"? Capisco la parte "del pavimento". Ma quando si aggiunge questo a trunc (sysdate), restituisce 18-AUG-15, non capisco questo. Grazie. – Mike

+0

@Mike. . . Lo farò, ma prima ho risolto la sintassi. Ho avuto 'sysdate' dove dovrebbe essere 'orderdate'. Stavo usando 'sysdate' per ottenere la logica giusta. –

3

in caso di necessità modo più semplice per ottenere intervallo di tempo - non posso aiutare con qualsiasi altra cosa come io non conosco le tabelle e dati:

-- Time interval - every 15 min from midnight -- 
SELECT To_Char(trunc(SYSDATE) + (LEVEL/1440*15), 'HH24:MI') interval_15_min 
    FROM dual 
CONNECT BY LEVEL <= 10 -- this is orbitraty 
/
SQL> 

INTERVAL_15_MIN 
-------------- 
00:15 
00:30 
00:45 
... 
Problemi correlati