2017-06-02 3 views
3

Wir haben die folgende SQL Server 2008-Beispieldatenbanktabelle, die Gehaltsinformationen pro Mitarbeiter über jeden Zahlungszeitraum zeigt (wöchentlich 52 oder 53 Wochen pro Jahr, nach dem Steuerjahr in Großbritannien, also Zahlungszeitraum Woche 1 ist 6. April und weiter).SQL Server: geben Sie verschiedene Anzahl von Zeiträumen zurück

Ich habe die Probe auf einen Mitarbeiter über eine Reihe von Zahlungszeiträumen begrenzt, die tatsächlichen Daten reichen viele Jahre zurück.

Ich bin verpflichtet, für jeden Mitarbeiter für die letzten 12 Wochen des Gehalts, wenn die Abfrage ausgeführt wird, Summen zu produzieren.

+------------+------------+---------+-------+ 
| EMPLOYEEID | PAYELEMENT | AMOUNT | HOURS | 
+------------+------------+---------+-------+ 
|  160062 | 1.0 Basic | 2724.64 | 468 | 
+------------+------------+---------+-------+ 

Jedoch habe ich einige Probleme zurück 12 verschiedene Perioden haben aufgrund der folgenden ...

  1. Periode 1 hat zwei Einträge
  2. Wenn im Urlaub keine Zeit, so zum Beispiel Woche aufgezeichnet wird 30 , 38 und 39 fehlen. In diesem Fall muss es zurückgehen, bis 12 aufgezeichnete Perioden verwendet werden.
  3. Going über das Jahr Ende von Periode 52 bis 1

Ich habe versucht, die letzten 12 Datensätze für jeden Mitarbeiter, sondern Punkt 1 oben verursachten nur 11 Perioden mit zu berechnen.

Ich habe auch versucht, Datumsunterschied auf dem Zahltag, aber Punkt 2 oben verursacht Perioden fehlen.

Muss ich einen Index pro Mitarbeiter hinzufügen, um 12 einzelne Zeiträume anzuzeigen?

+------------+------------+------+--------+--------+-------+------+------------------+ 
| EMPLOYEEID | PAYELEMENT | YEAR | PERIOD | AMOUNT | HOURS | RATE |  PAYDATE  | 
+------------+------------+------+--------+--------+-------+------+------------------+ 
|  160062 | 1.0 Basic | 2017 |  29 | 311.22 | 39 | 7.98 | 20/10/2016 00:00 | 
|  160062 | 1.0 Basic | 2017 |  31 | 311.22 | 39 | 7.98 | 03/11/2016 00:00 | 
|  160062 | 1.0 Basic | 2017 |  32 | 311.22 | 39 | 7.98 | 10/11/2016 00:00 | 
|  160062 | 1.0 Basic | 2017 |  33 | 311.22 | 39 | 7.98 | 17/11/2016 00:00 | 
|  160062 | 1.0 Basic | 2017 |  34 | 311.22 | 39 | 7.98 | 24/11/2016 00:00 | 
|  160062 | 1.0 Basic | 2017 |  35 | 311.22 | 39 | 7.98 | 01/12/2016 00:00 | 
|  160062 | 1.0 Basic | 2017 |  36 | 183.54 | 23 | 7.98 | 08/12/2016 00:00 | 
|  160062 | 1.0 Basic | 2017 |  37 | 311.22 | 39 | 7.98 | 15/12/2016 00:00 | 
|  160062 | 1.0 Basic | 2017 |  40 | 311.22 | 39 | 7.98 | 05/01/2017 00:00 | 
|  160062 | 1.0 Basic | 2017 |  41 | 311.22 | 39 | 7.98 | 12/01/2017 00:00 | 
|  160062 | 1.0 Basic | 2017 |  42 | 311.22 | 39 | 7.98 | 19/01/2017 00:00 | 
|  160062 | 1.0 Basic | 2017 |  43 | 311.22 | 39 | 7.98 | 26/01/2017 00:00 | 
|  160062 | 1.0 Basic | 2017 |  44 | 311.22 | 39 | 7.98 | 02/02/2017 00:00 | 
|  160062 | 1.0 Basic | 2017 |  45 | 311.22 | 39 | 7.98 | 09/02/2017 00:00 | 
|  160062 | 1.0 Basic | 2017 |  46 | 311.22 | 39 | 7.98 | 16/02/2017 00:00 | 
|  160062 | 1.0 Basic | 2017 |  47 | 311.22 | 39 | 7.98 | 23/02/2017 00:00 | 
|  160062 | 1.0 Basic | 2017 |  48 | 127.68 | 16 | 7.98 | 02/03/2017 00:00 | 
|  160062 | 1.0 Basic | 2017 |  49 | 311.22 | 39 | 7.98 | 09/03/2017 00:00 | 
|  160062 | 1.0 Basic | 2017 |  50 | 247.38 | 31 | 7.98 | 16/03/2017 00:00 | 
|  160062 | 1.0 Basic | 2017 |  51 | 311.22 | 39 | 7.98 | 23/03/2017 00:00 | 
|  160062 | 1.0 Basic | 2017 |  52 | 311.22 | 39 | 7.98 | 30/03/2017 00:00 | 
|  160062 | 1.0 Basic | 2018 |  1 | 247.38 | 31 | 7.98 | 06/04/2017 00:00 | 
|  160062 | 1.0 Basic | 2018 |  1 |  0 |  0 | 7.75 | 06/04/2017 00:00 | 
|  160062 | 1.0 Basic | 2018 |  2 | 311.22 | 39 | 7.98 | 13/04/2017 00:00 | 
|  160062 | 1.0 Basic | 2018 |  3 | 255.36 | 32 | 7.98 | 20/04/2017 00:00 | 
|  160062 | 1.0 Basic | 2018 |  4 | 247.38 | 31 | 7.98 | 27/04/2017 00:00 | 
|  160062 | 1.0 Basic | 2018 |  5 | 311.22 | 39 | 7.98 | 04/05/2017 00:00 | 
|  160062 | 1.0 Basic | 2018 |  6 | 127.68 | 16 | 7.98 | 11/05/2017 00:00 | 
|  160062 | 1.0 Basic | 2018 |  7 | 247.38 | 31 | 7.98 | 18/05/2017 00:00 | 
|  160062 | 1.0 Basic | 2018 |  8 | 277.31 | 34.75 | 7.98 | 25/05/2017 00:00 | 
+------------+------------+------+--------+--------+-------+------+------------------+ 
+0

Können Sie den Monat oder Woche von PAYDATE nehmen und als Periode verwenden? –

+0

Sind die Summe "Menge" und "Stunden" in Ihrem Beispiel oben korrekt? – SqlZim

+0

Das ist nur ein Beispiel für was aus einem 12-Wochen-Bereich zeigen könnte, könnte jeder Betrag abhängig von Stunden gearbeitet und zahlen –

Antwort

0

Hier ist ein weiterer Ansatz:

SELECT 
    EmployeeID, 
    PayElement, 
    sum(Amount) as Amount, 
    sum(Hours) as Hours 
FROM 
    (
    SELECT * 
    ,dense_rank() OVER (PARTITION BY EmployeeId ORDER BY PayDate DESC) as rank 
    FROM 
     Pay 
    ) ranked 
WHERE 
    rank <= 12 
GROUP BY 
    EmployeeID, 
    PayElement 

Wenn Nullwerte Probleme hier haben, die dann einfach WHERE Amount > 0 hinzufügen (oder vielleicht <> 0) an die innere Abfrage. Abhängig von Ihren Daten ist es möglich, dass Sie auch PayElement zur Partition By Klausel hinzufügen müssen (oder die innere WHERE Klausel).

Sie können dies testen über bei rextester.com/YDBL47689

1

Sie versuchen sollten:

;WITH Top12Periods AS (
    SELECT TOP 12 [YEAR], [PERIOD] 
    FROM @employeeTable 
    GROUP BY [YEAR], [PERIOD] 
    ORDER BY [YEAR] DESC, [PERIOD] DESC 
) 
SELECT [EMPLOYEEID], [PAYELEMENT], SUM([AMOUNT]) AS TOTAL_AMOUNT, SUM([HOURS]) AS TOTAL_HOURS, AVG([RATE]) AS AVERAGE_RATE, MIN ([PAYDATE]) [MIN_PAYDATE] 
FROM @employeeTable et 
    JOIN Top12Periods p ON et.[YEAR] = p.[YEAR] AND et.[PERIOD] = p.[PERIOD] 
GROUP BY [EMPLOYEEID], [PAYELEMENT] 
+0

Wenn das OP mehr als einen Mitarbeiter gleichzeitig zurückgeben möchte, wird dies nicht funktionieren. –

+0

Ja, Sie haben völlig Recht. Ich korrigiere die Anfrage. –

+0

Hmm, aber die geänderte Antwort wird nicht funktionieren, wenn die Angestellten in verschiedenen Zeiträumen voneinander bezahlt wurden. –

Verwandte Themen