2016-04-18 6 views
-1

Ich habe eine Eingabe wie:Falsche Ergebnisse, wenn sie von trunc (Zeitstempel) Gruppierung

01.03.16 15:48:45.772000000 
01.03.16 15:48:49.924000000 
01.03.16 21:31:08.320000000 
01.03.16 21:56:05.201000000 
02.03.16 00:11:10.552000000 
02.03.16 00:11:11.652000000 
02.03.16 01:31:14.359000000 
02.03.16 21:41:11.059000000 
03.03.16 00:11:06.850000000 
03.03.16 11:05:20.343000000 
03.03.16 16:07:07.148000000 
04.03.16 18:15:14.460000000 
04.03.16 18:55:39.206000000 
05.03.16 00:15:21.457000000 
05.03.16 00:20:14.908000000 
05.03.16 00:50:15.641000000 
07.03.16 08:45:19.526000000 
07.03.16 21:30:20.562000000 
07.03.16 21:45:20.402000000 
08.03.16 00:11:12.163000000 
08.03.16 14:37:46.607000000 
08.03.16 23:16:22.713000000 
08.03.16 23:16:22.715000000 

Nun ist die Idee von Datum zu gruppieren und zählen Reihen mit der Zeit vor und nach 06.30 Uhr . Ergebnis sollte so sein:

date  before after 
01.03.16 2 2 
02.03.16 3 1 
03.03.16 3 0 
04.03.16 0 2 
05.03.16 3 0 
07.03.16 1 2 
08.03.16 2 2 

Wenn ich Gruppe von trunc(mytimestamp) und case in der select Aussage macht mit mytimestamp Ich bin nicht das richtige Ergebnis zu bekommen.

Meine eigentliche Frage ist:

select trunc(tscreate), 
    to_timestamp(trunc(trunc(tscreate)),'dd.MM.yy') 
    + interval '17' hour + interval '30' minute as referenz_time, 
    sum(case when (tscreate < to_timestamp(trunc(trunc(tscreate)),'dd.MM.yy') 
    + interval '17' hour + interval '30' minute) then 1 else 0 end) as beforeTS, 
    sum(case when (tscreate >= to_timestamp(trunc(trunc(tscreate)),'dd.MM.yy') 
    + interval '17' hour + interval '30' minute) then 0 else 1 end) as afterTS 
from customer 
where app = 'abc' 
and tscreate >= to_date('01.03.2016','dd.MM.yyyy') 
group by trunc(tscreate) order by trunc(tscreate) 

Der Wert für beforTS scheint korrekt berechnet zu werden, aber afterTS ist immer die gleiche, wie beforeTS, und dies ist nicht möglich.

+0

Wenn Sie "CASE" auf den abgeschnittenen Wert verwenden müssen, verwenden Sie einfach 'trun'c im' CASE'; Wenn Sie "CASE" auf den gesamten Wert anwenden müssen, welches Ergebnis erwarten Sie? Wie könnten Sie zwei Zeilen mit dem gleichen abgeschnittenen Wert behandeln, aber mit verschiedenen Werten, die vom 'CASE' zurückgegeben werden? – Aleksej

+0

meine Abfrage loks wie: auswählen trunc (tscreate), to_timestamp (trunc (trunc (tscreate)), 'dd.MM.yy') + Intervall '17' Stunde + Intervall '30' Minute als Refrenz_time, Summe (case when (tscreate = to_timestamp (trunc (trunc (tscreate)), 'dd.MM.yy') + Intervall '17' Stunde + Intervall '30' Minute) dann 0 sonst 1 Ende) als afterTS von Kunde wo app = 'abc' und tscreate> = to_date ('01 .03.2016 ',' dd.MM.yyyy ') Gruppe nach trunc (tscreate) Sortierung nach trunc (tscreate) – user

+0

Bitte fügen Sie den Code der Frage hinzu, nicht als Kommentar; und schließe das Ergebnis ein, das du daraus erhältst. Ihre Abfrage ist kein Fehler, aber nicht das erwartete Ergebnis, oder? Obwohl es so ist, wenn Sie nur 'then 0 else 1' in' then 1 else 0' ändern, wird Ihre Fallbedingung umgekehrt, so dass Sie diese Logik auch nicht rückgängig machen wollen. Sie heben sich gegenseitig auf. (Ihre Frage sagt auch 6:30, aber der Code sagt 5:30). Also ... ich bin mir nicht sicher, was deine Frage ist? –

Antwort

1

Die Abfrage, die Sie als Kommentar gepostet fast funktioniert - es ist nicht Fehler tritt aber wird nicht das Ergebnis, das Sie sagten, Sie wollten. In der zweiten case Ausdruck haben Sie Änderung < zu >=1 aber Sie haben then 0 else 1-then 1 else 0auch geändert und diese beiden Änderungen seitig aufheben - die Logik der beiden Enden die gleiche, und sie sind beide Zählzeit vor 17:30 Uhr.

Also nur zur Festsetzung, dass das Ergebnis werden Sie wollen:

select trunc(tscreate), 
    to_timestamp(trunc(trunc(tscreate)),'dd.MM.yy') 
    + interval '17' hour + interval '30' minute as referenz_time, 
    sum(case when (tscreate < to_timestamp(trunc(trunc(tscreate)),'dd.MM.yy') 
    + interval '17' hour + interval '30' minute) then 1 else 0 end) as beforeTS, 
    sum(case when (tscreate >= to_timestamp(trunc(trunc(tscreate)),'dd.MM.yy') 
    + interval '17' hour + interval '30' minute) then 1 else 0 end) as afterTS 
from customer 
where app = 'abc' 
and tscreate >= to_date('01.03.2016','dd.MM.yyyy') 
group by trunc(tscreate) 
order by trunc(tscreate); 

TRUNC(TSCREATE) REFERENZ_TIME     BEFORETS AFTERTS 
--------------- ---------------------------- ---------- ---------- 
01-MAR-16  01-MAR-16 17.30.00.000000000   2   2 
02-MAR-16  02-MAR-16 17.30.00.000000000   3   1 
03-MAR-16  03-MAR-16 17.30.00.000000000   3   0 
04-MAR-16  04-MAR-16 17.30.00.000000000   0   2 
05-MAR-16  05-MAR-16 17.30.00.000000000   3   0 
07-MAR-16  07-MAR-16 17.30.00.000000000   1   2 
08-MAR-16  08-MAR-16 17.30.00.000000000   2   2 

ich ihm etwas vereinfachen würde, aber einige dieser sind auf dem persönlichen Geschmack:

select trunc(tscreate), 
    cast(trunc(tscreate) 
    + interval '17:30' hour to minute as timestamp) as referenz_time, 
    count(case when tscreate < cast(trunc(tscreate) 
    + interval '17:30' hour to minute as timestamp) then 1 end) as beforeTS, 
    count(case when tscreate >= cast(trunc(tscreate) 
    + interval '17:30' hour to minute as timestamp) then 1 end) as afterTS 
from customer 
where app = 'abc' 
and tscreate >= timestamp '2016-03-01 00:00:00' 
group by trunc(tscreate) 
order by trunc(tscreate); 

das das gleiche Ergebnis erhält . Oder wenn Sie Intervalle nicht mögen Sie Datumsberechnungen stattdessen verwenden können.

select trunc(tscreate), 
    trunc(tscreate) + 17.5/24 as referenz_time, 
    count(case when tscreate < cast(trunc(tscreate) + 17.5/24 as timestamp) then 1 end) as beforeTS, 
    count(case when tscreate >= cast(trunc(tscreate) + 17.5/24 as timestamp) then 1 end) as afterTS 
from customer 
where app = 'abc' 
and tscreate >= timestamp '2016-03-01 00:00:00' 
group by trunc(tscreate) 
order by trunc(tscreate); 

(Man könnte sogar einen String-Vergleich der extrahierten Zeit tun, als David Wallace kurz vorgeschlagen, das heißt to_char(tscreate, 'HH24:MI') < '17:30' Aber auch wenn das ‚sicher "Bei 24-Stunden-Zeiten bleibe ich lieber beim ursprünglichen Datentyp."

Ich bin mir nicht sicher, dass Sie wirklich referenz_time als Zeitstempel benötigen, und beide Wege, wenn dies zur Anzeige ist, sollten Sie die Daten formatieren und Zeitstempel explizit, anstatt sich auf NLS-Einstellungen zu verlassen.

+0

vielen Dank! Ich habe ein paar Stunden mit diesem Thema verbracht. :) – user

0

Sie können immer noch trunc(mytimestamp) überall verwenden:

select to_char(trunc(mytimestamp), 'DD.MM.YYYY') 
from my_table 
group by trunc(mytimestamp) 
Verwandte Themen