2016-12-18 5 views
1

Ich versuche, Datensätze nach Stunden über mehrere Tage mit Knex zu gruppieren. So würde zum Beispiel 09.00 Uhr sein:Summe zählt über mehrere Tage und Gruppe für Stunde

{ 
    hour: 9AM, // for days 12/11, 12/12, 12/13 
    count: 10 // 10 Ids total over those days for hour 9AM 
} 

die Datensätze in dieser Momentaufnahme gegeben, wie kann ich sie in hour Eimer über mehrere Tage aggregieren?

enter image description here

Wenn ich Ausgang der Abfrageergebnisse, Sie zwei getrennte Ergebnisse für 19:00 für 12/12 und 12/13 sehen können. Diese zwei Tage zählt müssen in einer hour 19:00 Gruppierung zusammengefasst werden:

ROWS [ anonymous { 
    session_ids: [ 3200 ], 
    hour: 2016-12-12T14:00:00.000Z, 
    count: '1' }, 
    anonymous { 
    session_ids: [ 3201 ], 
    hour: 2016-12-12T15:00:00.000Z, 
    count: '1' }, 
    anonymous { 
    session_ids: [ 3203, 3202 ], 
    hour: 2016-12-12T19:00:00.000Z, 
    count: '2' }, 
    anonymous { 
    session_ids: [ 3204, 3205 ], 
    hour: 2016-12-13T19:00:00.000Z, // This count should be aggregated into the `19:00` grouping above 
    count: '2' } ] 

Meine aktuelle Abfrage:

var qry = db.knex 
    .select(db.knex.raw("array_agg(t2.id) as session_ids, date_trunc('hour', t2.start_timestamp) as hour")) 
    .count('*') 
    .from('sessions as t2') 
    .groupByRaw("date_trunc('hour', t2.start_timestamp)") 
    .orderBy(db.knex.raw("date_trunc('hour', t2.start_timestamp)")); 

Antwort

4

Verwenden EXTRACT, nicht date_trunc:

var qry = db.knex 
    .select(db.knex.raw("array_agg(t2.id) as session_ids, extract('hour' from t2.start_timestamp) as hour")) 
    .count('*') 
    .from('sessions as t2') 
    .groupByRaw("extract('hour' from t2.start_timestamp)") 
    .orderBy(db.knex.raw("extract('hour' from t2.start_timestamp)")); 

date_trunc kürzt einen Zeitstempel auf die angegebene Genauigkeit (dh die GROUP BY wird nicht funktionieren, wie die Tage von zwei Zeitstempel mit dem gleichen ‚Stunde‘ Feld noch verschieden sein können):

SELECT date_trunc('hour', NOW()); 
┌────────────────────────┐ 
│  date_trunc  │ 
├────────────────────────┤ 
│ 2016-12-18 19:00:00+01 │ 
└────────────────────────┘ 
(1 row) 

während EXTRACT in dem Feld holt Sie fragte nach:

SELECT extract('hour' from NOW()); 
┌───────────┐ 
│ date_part │ 
├───────────┤ 
│  19 │ 
└───────────┘ 
(1 row) 
+0

@Growler: verpasste die 'date_trunc' in der' ORDER BY'-Klausel. Ich habe es repariert. – Marth

+0

Das ist großartig. Wofür ist "date_trunc" gut? Und was meinst du mit 'holt das spezifische Feld, nach dem du gefragt hast'? Gibt 'trunc' nicht auch eine' 19th' Stunde? – Growler

+0

@Growler: Sie können sehen, was 'date_trunc' in den' Stunde'-Feldern in Ihrer Frage zurückgibt. Es kann nützlich sein, wenn Sie 2 Zeitstempel mit etwas Spielraum vergleichen möchten: Wenn Sie beispielsweise nur Daten bis zur Minute vergleichen möchten, können Sie 'date_trunc ('minute', ts) = date_trunc (...)' verwenden, das würde die Sekunden-/Millisekunden-Genauigkeit verwerfen (auf beiden Seiten auf 0 setzen, bevor die Gleichheit geprüft wird). – Marth

Verwandte Themen