2

I eine Tabelle EmpLunch wie unten haben:mehr Datensätze in einer Zeile

EmployeeId BusinessDate PunchIn Lunch1Start Lunch1End Lunch2Start Lunch2End PunchOut 
101   10/12/2017  9:00 AM 1:00 PM  1:30 PM       5:00 PM 
101   10/13/2017  9:00 AM 1:00 PM  1:28 PM       5:00 PM 
101   10/14/2017  9:00 AM 1:00 PM  1:28 PM 3:00 PM 3:28 PM  5:00 PM 
101   10/15/2017  9:00 AM             5:00 PM 

I Notwendigkeit, die Daten in einer zusätzlichen Spalte Errorcode basierend auf folgende Logik zu bevölkern:

Error Code = 
1 = Lunch 1 Not Taken 
2 = Lunch 1 Less Than 30 Minutes 
3 = Lunch 1 Started 300 Minutes Past IN Punch 
4 = Lunch 2 Not Taken 
5 = Lunch 2 Less Than 30 Minutes 

Die resultierende Tabelle Sould wie zum Beispiel:

EmployeeId BusinessDate PunchIn Lunch1Start Lunch1End Lunch2Start Lunch2End PunchOut ErrorCode 
101   10/12/2017  9:00 AM 1:00 PM  1:30 PM       5:00 PM  4 
101   10/13/2017  9:00 AM 1:00 PM  1:28 PM       5:00 PM  2, 4 
101   10/14/2017  9:00 AM 1:00 PM  1:28 PM 3:00 PM 3:28 PM  5:00 PM  2, 5 
101   10/15/2017  9:00 AM             5:00 PM  1 

ich habe einen einfachen Code wie unten geschrieben:

Select *, 
CASE WHEN Lunch1Start IS NULL THEN '1' 
WHEN DATEDIFF(MINUTE, Lunch1Start, Lunch1End) < 30.0 THEN '2' 
WHEN DATEDIFF(MINUTE, LunchEnd1, PunchIn) < 300.0 THEN '3' 
WHEN Lunch2Start IS NULL THEN '4' 
WHEN DATEDIFF(MINUTE, Lunch2End, LunchI2Start) < 30.0 THEN '5' 
END LunchError 
From EmpLunch 

Die obige Abfrage gibt nicht mehrere Datensätze in einer Zelle (wie Datensatz für 10/13 und 10/14 in der obigen Tabelle). Meine Abfrage gibt nur den ersten Wert in der Spalte aus. Bitte schlagen Sie einen Weg vor, um das Ziel zu erreichen (durch Kommas getrennte Werte in der Spalte).

Antwort

3

Sie müssen nur Ergebnis von drei verschiedenen Fällen erfassen. Zuerst für Fehlercodes 1 und 2, die zweite für den Fehlercode 3 und die dritte für die Codes 4 und 5 wie folgt aus:

Select 
    *, STUFF(CASE WHEN Lunch1Start IS NULL THEN ', 1' WHEN DATEDIFF(MINUTE, Lunch1Start, Lunch1End) < 30.0 THEN ', 2' ELSE '' END 
    + CASE WHEN DATEDIFF(MINUTE, LunchEnd1, PunchIn) < 300.0 THEN ', 3' ELSE '' END 
    + CASE WHEN Lunch2Start IS NULL THEN ', 4' WHEN DATEDIFF(MINUTE, Lunch2End, LunchI2Start) < 30.0 THEN ', 5' ELSE '' END,1,2,'') LunchError 
From EmpLunch 
3

Sie können die einzelnen Werte mit separaten case Ausdrücke miteinander verkettet erhalten. Hier ist eine Methode:

select el.*, 
     stuff((case when Lunch1Start is null then ', 1' else '' end) + 
       (case when datediff(minute, Lunch1Start, Lunch1End) < 30 then ', 2' else '' end) + 
       (case when datediff(minute, LunchEnd1, PunchIn) < 300 then ', 3' else '' end) + 
       (case when Lunch2Start IS NULL then ', 4' else '' end) + 
       (case when datediff(minute, Lunch2End, LunchI2Start) < 30 then ', 5' else '' end), 1, 2, '') 
from EmpLunch el; 

Die stuff() entfernt die Separatoren. Beachten Sie auch, dass diese Version eine leere Zeichenfolge zurückgibt, anstatt NULL, wenn keine Fehler vorliegen. Wenn Sie NULL wollen, dann nullif() verwenden:

select el.*, 
     nullif(stuff((case when Lunch1Start is null then ', 1' else '' end) + 
        (case when datediff(minute, Lunch1Start, Lunch1End) < 30 then ', 2' else '' end) + 
        (case when datediff(minute, LunchEnd1, PunchIn) < 300 then ', 3' else '' end) + 
        (case when Lunch2Start IS NULL then ', 4' else '' end) + 
        (case when datediff(minute, Lunch2End, LunchI2Start) < 30 then ', 5' else '' end), 1, 2, ''), '') 
from EmpLunch el; 

Beachten Sie, dass datediff() eine ganze Zahl zurückgibt. Es kann auch nicht genau das tun, was Sie wollen, weil es "Einheitengrenzen" zwischen den Werten zählt. Ich würde diese Logik statt:

select el.*, 
     stuff((case when Lunch1Start is null then ', 1' else '' end) + 
       (case when Lunch1Start < dateadd(minute, -30, Lunch1End) then ', 2' else '' end) + 
       (case when LunchEnd1 < dateadd(minute, -300) < 300 then ', 3' else '' end) + 
       (case when Lunch2Start IS NULL then ', 4' else '' end) + 
       (case when Lunch2End < dateadd(minute, -30, LunchI2Start) then ', 5' else '' end), 1, 2, '') 
from EmpLunch el; 
+0

Dank Gordon !! – user1326379

0

-Mine arbeitet:

DROP TABLE IF EXISTS category --SQL 2016/17 
    go 
    CREATE TABLE Category 
    (id int IDENTITY (1,1) NOT NULL Primary Key 
    ,Punchin time 
    ,lunch1Start time 
    ,lunch1End time 
    ,lunch2Start time 
    ,lunch2End time 
    ,Punchout time 
    ,LunchError as CASE when lunch1start is null then '1' WHEN DATEDIFF(MINUTE,lunch1start,lunch1end) < 30 THEN '2' 
     WHEN DATEDIFF(MINUTE,lunch1end, punchin) < 300 THEN '3' 
     WHEN lunch2start is null then '4' end 
     + ', '+ CASE WHEN lunch2start is null then '4' WHEN DATEDIFF(MINUTE,lunch2start,lunch2end) < 30 THEN '5' 
     WHEN DATEDIFF(MINUTE,lunch2start,lunch2end) < 300 THEN '3' 
     END 

    ) 

    INSERT category(punchin, lunch1Start, lunch1End, Punchout) 
    VALUES ('9:00 am','1:00 pm', '1:30 pm', '5:00 pm') 

    INSERT category(punchin, lunch1Start, lunch1End, Punchout) 
    VALUES('9:00 am','1:00 pm', '1:28 pm', '5:00 pm') 

    INSERT category(punchin, lunch1Start, lunch1End, lunch2Start, lunch2End, Punchout) 
    VALUES ('9:00 am','1:00 pm', '1:28 pm', '3:00 pm', '3:28','5:00 pm') 

    INSERT category(punchin, Punchout) 
    VALUES ('9:00 am','5:00 pm') 
Verwandte Themen