Firebird SP Minuten summieren

lapadula

Aktiver Benutzer
Beiträge
33
Hallo, ich weiss nicht wohin mit dem Thema Firebird, auf Wikipedio steht, dass die Syntax so ähnlich ist wie Oracle, deslhab habe ich das Thema hier eröffnet.

Es geht um eine Stored Procedure an der ich gerade bastele und nicht weiterkomme.

Aus einer Tabelle wo alle Zeitstempel aller Mitarbeiter gespeichert werden, soll herausgefunden werden, ob ein bestimmter Mitarbeiter im Plus oder Minus ist.

Ich habe ein Select womit ich alle Zeitstempel in einem bestimmten Zeitraum und einer bestimmten User_ID abfrage.

Pro Tag gibt es eine gerade Anzahl an Stempel, sieht folgendermaßen aus:

02.05.2018, 08:35:06.000
02.05.2018, 11:58:02.000
02.05.2018, 12:35:51.000
02.05.2018, 16:58:30.000
03.05.2018, 08:37:03.000
03.05.2018, 12:12:43.000
03.05.2018, 12:34:47.000
03.05.2018, 17:02:20.000
04.05.2018, 08:37:05.000
04.05.2018, 12:00:55.000
04.05.2018, 12:29:25.000
15.05.2018, 08:31:48.000
15.05.2018, 12:01:27.000
15.05.2018, 12:18:19.000
15.05.2018, 16:59:14.000
15.05.2018, 16:59:20.000


Ich habe mir überlegt, mit einer Schleife alle Einträge durchzugehen, eine Hilfsvariable hochzuzählen und zu schauen ob diese gerade oder ungerade ist, die Zwischenergebnise aus der Abfrage in einer Hilfsvariable zwischenzuspeichern und die Differenz in Minuten summieren.

Sieht folgendermaßen aus:

Code:
SET TERM ^ ;
ALTER PROCEDURE SP_ATTENDANT
RETURNS (
    Datum Timestamp,
    DiffMinuten Integer,
    Ergebnis Integer,
    x Timestamp,
    y Timestamp
    )
AS
declare variable i Integer;
declare variable Summe Integer;

BEGIN
    i = 0;
    Summe = 0;
    FOR SELECT a."WHEN"
        FROM ATTENDANT a
        WHERE cast(a."WHEN" as date) >= '01.05.2018'
            AND cast(a."WHEN" as date) < current_date
            AND a.USERID = 10
        INTO :Datum
    DO
    BEGIN
        i = i + 1;
        if (mod(i, 2) = 0) then
            x = Datum;
        else
            y = Datum;
            
    Summe = Summe + DATEDIFF(MINUTE FROM (x) TO (y));
    END
    Ergebnis = Summe;
    
END^
SET TERM ; ^

GRANT EXECUTE
 ON PROCEDURE SP_ATTENDANT TO  SYSDBA;


Allerdings bekomme ich beim Ergebnis immer NULL. Ich verstricke mich hier auch in der Schleife, vllt gibt es eine elegantere Methode, da ich auch noch den Tageswechsel mit beachten muss.
 
Werbung:
Pro Tag gibt es eine gerade Anzahl an Stempel, sieht folgendermaßen aus:


04.05.2018, 08:37:05.000
04.05.2018, 12:00:55.000
04.05.2018, 12:29:25.000
15.05.2018, 08:31:48.000
15.05.2018, 12:01:27.000
15.05.2018, 12:18:19.000
15.05.2018, 16:59:14.000
15.05.2018, 16:59:20.000

3 Einträge am 4.5., 5 Einträge am 15.5. Wenn ich mich recht an meine Grundschulzeit erinnere, sind 3 und 5 aber ungerade Zahlen.

Sollen das Kommen-Gehen - Buchungen sein?
 
Ups, da habe ich wohl falsch kopiert oder der MA hat sich da falsch eingestempelt, die Zeiterfassung war zu der Zeit neu installiert.

Zu deiner Frage, ja es sind kommen und gehen Stempel, daher müsste die Anzahl gerade sein. Bei den meisten ist: Kommen, zur Pause, von der Pause und Gehen.

Es gibt auch einen Feld für 1 kommen und 0 gehen, hilft mir aber auch nicht wirklich weiter.
 
Also, ich habe mal Deine Daten in eine Tabelle getan. Die Spalte t nur zum Import, um daraus ts vom Typ "timestamp" zu ermitteln.

Code:
test=*# select * from lapadula ;
            t             |         ts         
--------------------------+---------------------
 02.05.2018, 08:35:06.000 | 2018-05-02 08:35:06
 02.05.2018, 11:58:02.000 | 2018-05-02 11:58:02
 02.05.2018, 12:35:51.000 | 2018-05-02 12:35:51
 02.05.2018, 16:58:30.000 | 2018-05-02 16:58:30
 03.05.2018, 08:37:03.000 | 2018-05-03 08:37:03
 03.05.2018, 12:12:43.000 | 2018-05-03 12:12:43
 03.05.2018, 12:34:47.000 | 2018-05-03 12:34:47
 03.05.2018, 17:02:20.000 | 2018-05-03 17:02:20
 04.05.2018, 08:37:05.000 | 2018-05-04 08:37:05
 04.05.2018, 12:00:55.000 | 2018-05-04 12:00:55
 04.05.2018, 12:29:25.000 | 2018-05-04 12:29:25
 15.05.2018, 08:31:48.000 | 2018-05-15 08:31:48
 15.05.2018, 12:01:27.000 | 2018-05-15 12:01:27
 15.05.2018, 12:18:19.000 | 2018-05-15 12:18:19
 15.05.2018, 16:59:14.000 | 2018-05-15 16:59:14
 15.05.2018, 16:59:20.000 | 2018-05-15 16:59:20
(16 Zeilen)

Nun kann man mit Window-Funktionen (ich weiß nicht, ob Firebird das kann) die Zeiten berechnen:

Code:
test=*# with tmp as (select ts, case when (row_number() over (partition by ts::date))%2 = 1 then 'kommt' else 'geht' end as buchung from lapadula) select *, case when buchung = 'geht' then ts-lag(ts) over (order by ts) end as zeit from tmp ;
         ts          | buchung |   zeit   
---------------------+---------+----------
 2018-05-02 08:35:06 | kommt   |
 2018-05-02 11:58:02 | geht    | 03:22:56
 2018-05-02 12:35:51 | kommt   |
 2018-05-02 16:58:30 | geht    | 04:22:39
 2018-05-03 08:37:03 | kommt   |
 2018-05-03 12:12:43 | geht    | 03:35:40
 2018-05-03 12:34:47 | kommt   |
 2018-05-03 17:02:20 | geht    | 04:27:33
 2018-05-04 08:37:05 | kommt   |
 2018-05-04 12:00:55 | geht    | 03:23:50
 2018-05-04 12:29:25 | kommt   |
 2018-05-15 08:31:48 | kommt   |
 2018-05-15 12:01:27 | geht    | 03:29:39
 2018-05-15 12:18:19 | kommt   |
 2018-05-15 16:59:14 | geht    | 04:40:55
 2018-05-15 16:59:20 | kommt   |
(16 Zeilen)

test=*#

Kann man natürlich noch zusammenfassen:
Code:
test=*# with tmp as (select ts, case when (row_number() over (partition by ts::date))%2 = 1 then 'kommt' else 'geht' end as buchung from lapadula), tmp2 as ( select *, case when buchung = 'geht' then ts-lag(ts) over (order by ts) end as zeit from tmp ) select ts::date, sum(zeit) from tmp2 group by ts::date;
     ts     |   sum   
------------+----------
 2018-05-15 | 08:10:34
 2018-05-04 | 03:23:50
 2018-05-03 | 08:03:13
 2018-05-02 | 07:45:35
(4 Zeilen)

test=*#

So schön kann SQL sein, ohne stored Procs oder so ;-)
 
Werbung:
Zurück
Oben