Frage

Ich schreibe eine einfache Zeiterfassung Programm zu meinen eigenen Projekten zu verwalten. Ich bin ein großer Fan von Reporting-Code in der Datenbank zu halten, so dass ich habe versucht, ein paar sprocs zu erstellen, die die Rechnungen und Zeiterfassungen usw. erzeugen.

Ich habe eine Tabelle, die Clock Aktionen, IE "Punch-In" und "Punch Out" enthält. Es enthält auch den Benutzer, dass diese Aktion hat, das Projekt mit der Aktion verbunden ist, und die aktuelle Datum / Uhrzeit.

Ich kann aus dieser Tabelle wählen Uhr für eine bestimmte Zeit / Projekt- / und Benutzer in die bekommen, aber ich will es aggregieren nach unten, so dass jede Uhr in und aus 2 Zeilen zu einer einzigen Zeile mit Gesamtzeit umgewandelt wird.

Zum Beispiel, hier ist ein Beispiel für die Ausgabe:

ClockActionID        ActionType DateTime
-------------------- ---------- -----------------------
17                   1          2008-11-08 18:33:56.000
18                   2          2008-11-08 18:33:59.587
19                   1          2008-11-08 18:34:01.023
20                   2          2008-11-08 18:34:02.037
21                   1          2008-11-08 18:45:06.317
22                   2          2008-11-08 18:46:14.597
23                   1          2008-11-08 18:46:16.283
24                   2          2008-11-08 18:46:17.173
25                   1          2008-11-08 18:50:37.830
26                   2          2008-11-08 18:50:39.737
27                   1          2008-11-08 18:50:40.547

(11 row(s) affected)

Wo Action 1 "ClockIn" und Action 2 "ClockOut". Ich ausgeästet auch die Benutzer, Projekt, und Beschreibung Spalten der Kürze halber.

Ich brauche zu erzeugen, in reiner SQL, ein Ergebnis gesetzt wie:

Description   |    Total Time

Für jede ClockIn / ClockOut Paar.

Ich stelle dar, die eigentlich ziemlich einfach sein, ich bin nur nicht ganz sicher, welche Art und Weise es zu nähern.

EDIT: Der Benutzer wird in mehrere Projekte Uhr gleichzeitig in der Lage, wenn auch zunächst das Ergebnis eines einzelnen Projekts Eingrenzung, dies keinen Unterschied zu der Logik hier machen sollte

.
War es hilfreich?

Lösung

Ich bin damit einverstanden, dass das Design nicht die größten ist - ein Ereignis basierte Struktur mit einer einzigen Zeile für Start-Ende wird wahrscheinlich Ihnen eine Menge Zeit sparen. In diesem Fall Sie einen Datensatz mit einem Null-Enddatums schaffen könnten, wenn jemand taktet in. Dann füllen Sie das Enddatum, wenn sie Uhr aus.

Aber das ist nicht das, was Sie gefragt. Dies ist die Lösung für Ihr Problem:

DECLARE @clock TABLE (ClockActionID INT PRIMARY KEY IDENTITY, ActionType INT, ActionDateTime DATETIME)

INSERT INTO @clock (ActionType, ActionDateTime) VALUES (1,'20080101 00:00:00')
INSERT INTO @clock (ActionType, ActionDateTime) VALUES (2,'20080101 00:01:00')
INSERT INTO @clock (ActionType, ActionDateTime) VALUES (1,'20080101 00:02:00')
INSERT INTO @clock (ActionType, ActionDateTime) VALUES (2,'20080101 00:03:00')
INSERT INTO @clock (ActionType, ActionDateTime) VALUES (1,'20080101 00:04:00')
INSERT INTO @clock (ActionType, ActionDateTime) VALUES (2,'20080101 00:05:00')
INSERT INTO @clock (ActionType, ActionDateTime) VALUES (1,'20080101 00:06:00')
INSERT INTO @clock (ActionType, ActionDateTime) VALUES (2,'20080101 00:07:00')
INSERT INTO @clock (ActionType, ActionDateTime) VALUES (1,'20080101 00:08:12')
INSERT INTO @clock (ActionType, ActionDateTime) VALUES (2,'20080101 00:09:00')

-- Get the range
SELECT ActionDateTime CheckIn, 
  (SELECT TOP 1 ActionDateTime 
   FROM @clock C2 
   WHERE C2.ActionDateTime > C.ActionDateTime) CheckOut   
FROM @clock C
WHERE ActionType = 1

-- Get the duration
SELECT DATEDIFF(second, ActionDateTime, 
  (SELECT TOP 1 ActionDateTime 
   FROM @clock C2 
   WHERE C2.ActionDateTime > C.ActionDateTime)
  ) / 60.0 Duration_Minutes
FROM @clock C
WHERE ActionType = 1

Beachten Sie, dass ich eine Tabelle Variable bin mit, die mit MS SQL Server funktioniert nur zum Testen. Ändern Sie nach Bedarf. Beachten Sie auch, dass SQL Server 2000 führt keine gut mit Abfragen wie folgt. Hier sind die Testergebnisse:

CheckIn                 CheckOut
2008-01-01 00:00:00.000 2008-01-01 00:01:00.000
2008-01-01 00:02:00.000 2008-01-01 00:03:00.000
2008-01-01 00:04:00.000 2008-01-01 00:05:00.000
2008-01-01 00:06:00.000 2008-01-01 00:07:00.000
2008-01-01 00:08:12.000 2008-01-01 00:09:00.000

Duration_Minutes
1.000000
1.000000
1.000000
1.000000
0.800000

Andere Tipps

Ich denke, Ihre ursprünglichen Speicher Schema fehlerhaft ist. Sie sind es aus der Sicht der Uhr zu schauen, damit ClockAction. Warum nicht aus der Perspektive des Projektes?

TABLE ProjectAction (projectID, Benutzer-ID, Typ, Start, Ende)

Dann wird ein einfacher GROUP BY sollte es tun.

Haben Sie sich Gedanken über Dinge wie:

  • jemand vergisst zu takten aus, und so scheint es, sie getaktet in zweimal?
  • jemand vergisst zu takten in, und somit scheint es, sie getaktet zweimal aus?

Im ersten Fall ist es richtig, den zweiten Takt-in einfach zu ignorieren? Die akzeptierte Antwort bindet beid Uhr-in auf den gleichen Takt-out. Ist das richtig?

Im zweiten Fall, der zweite Takt-out ignoriert. Ist das richtig?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top