2016-04-04 10 views
0

Şirket politikaları nedeniyle çalıştığım asıl sorguyu veremem ancak arıza ve genel fikir. Bir çalışanın çalışıp çalışmadığı ve çalışanın çalıştığı her gün için kayıt tutan bir katılım kaydımız vardır. Bu ve bu tarih arasında çalışanın 5 vardiya çalıştığı ile ilgili bir özet yapmaya çalışıyorum. Oturduğum problem, özel bir çalışanın işyerinde A'da 2 gün çalıştığı ve daha sonra işyerine taşındığıdır. B işyerinde birkaç gün sonra işçinin daha sonra A işyerine devredilmişti.Katılım özet raporu rapora

Benim girişimim, çalışanın 1-Ocak'ta işyerinde A çalışmaya başladığını ve sadece 2 çalışma vardiyasıyla 10-Ocak'ta sona erdiğini gösterdi. Çalışma yerindeki bir grubum var ve başlangıç ​​ve bitiş tarihleri ​​min ve maksimum seçimdir.

SELECT att.Employee, att.Workplace, dte.BeginDate, dte.EndDate, shf.WorkShift FROM 
(SELECT * FROM Attendance WHERE WorkDate BETWEEN '1-Jan' AND '30-Jan') att 
CROSS APPLY (SELECT COUNT(Shift) WorkShift FROM Attendance WHERE WorkDate BETWEEN '1-Jan' AND '30-Jan' AND Employee = att.Employee AND WorkPlace = att.WorkPlace AND Shift = 'Worked') shf 
CROSS APPLY (SELECT MAX(WorkDate) BeginDate, MIN(WorkDate) EndDate FROM Attendance WHERE WorkDate BETWEEN '1-Jan' AND '30-Jan' AND Employee = att.Employee AND WorkPlace = att.WorkPlace) dte 

Yani kayıtları böyle görünmelidir bu çalışanların

(çok kötü grid için üzgünüm, ben güzel görünmesi için nasıl bilmiyorum, bunu daha iyi bakmak için düzenlemek için daha fazla bekliyoruz)
| Name | Workplace | beginDate | endDate | WorkShift | 
| Jane | WorkPlaceA | 1-Jan  | 2-Jan | 2   | 
| Jane | WorkPlaceB | 3-Jan  | 8-Jan | 5   | 
| Jane | WorkPlaceA | 9-Jan  | 10-Jan | 2   | 

katılım tablo sana CTE'ler kullanarak gerçekleştirebilirsiniz inanıyoruz bu

| Name | Workplace | Date | Shift | 
| Jane | WorkplaceA | 1-Jan | Worked | 
| Jane | WorkplaceA | 2-Jan | Worked | 
| Jane | WorkplaceB | 3-Jan | Worked | 
| Jane | WorkplaceB | 4-Jan | Worked | 
| Jane | WorkplaceB | 5-Jan | Worked | 
| Jane | WorkplaceA | 6-Jan | Absent | 
| Jane | WorkplaceA | 7-Jan | Absent | 
| Jane | WorkplaceA | 8-Jan | Worked | 
| Jane | WorkplaceB | 9-Jan | Worked | 
| Jane | WorkplaceB | 10-Jan | Worked | 
+0

@Tanner sayılmaz, ben eksik olduğunu fark olduğunu kısa sürede tekrar tekrar okumaya başladı. Hatırlattığın için teşekkürler –

cevap

1

şöyle görünür. İşte beklenen değerleri gösteren örnek bir çalışma kodu.

;WITH CTE1 AS (
SELECT Employee, WorkPlace, TransactionDate, 
    ROW_NUMBER() OVER(PARTITION BY WorkPlace ORDER BY TransactionDate) AS WP, 
    ROW_NUMBER() OVER(ORDER BY TransactionDate) AS RN FROM Attendance WHERE Shift = 'Worked'), 
    CTE2 AS (SELECT Employee, WorkPlace, TransactionDate, WP, RN, WP-RN AS GB FROM CTE1), 
    CTE3 AS (SELECT Employee, WorkPlace, MIN(TransactionDate) AS TransactionDate, COUNT(1) AS Shifts FROM CTE2 GROUP BY Employee, WorkPlace, GB) 

SELECT Employee, WorkPlace, TransactionDate AS [Start Date], DATEADD(DAY,Shifts - 1,TransactionDate) AS [End Date], Shifts FROM CTE3 ORDER BY TransactionDate ASC 
+0

Neredeyse% 100 çalışan, çalışanın çalışan bir vardiyadan vardiyaya kayması sorunudur. EndDate ilk Absent vardiyasında durur. Bunu aşmanın bir yolu var. Çalışanın bir işyerinde ne zaman işe yarayıp başlamadığına bakmak için başlangıç ​​ve bitiş tarihlerini göstermesi gerekir. –

+0

Bu gerekli olanı almak için kullandığım nihai çözüm olmasa da, doğru çözüm için bana yardımcı oldu. Ve bu benim soruma cevap verdi. teşekkürler @Randolph –

0

Verilen çıktıların yanlış olduğunu düşünüyorum.

Tabloyu doldurma şeklinizin yanlış olduğunu düşünüyorum.

benim sorgu kontrol edin, daha fazla optmize olabilir, bu devamsızlık günleri

şimdi düzenleme yaptı
declare @t table(Name varchar(100),Workplace varchar(100), AttnDate date ,Shifts varchar(100)) 
insert into @t values 
('Jane','WorkplaceA',' 1-Jan-16','Worked') 
,('Jane','WorkplaceA',' 2-Jan-16','Worked') 
,('Jane','WorkplaceB',' 3-Jan-16','Worked') 
,('Jane','WorkplaceB',' 4-Jan-16','Worked') 
,('Jane','WorkplaceB',' 5-Jan-16','Worked') 
,('Jane','WorkplaceA',' 6-Jan-16','Absent') 
,('Jane','WorkplaceA',' 7-Jan-16','Absent') 
,('Jane','WorkplaceA',' 8-Jan-16','Worked') 
,('Jane','WorkplaceB',' 9-Jan-16','Worked') 
,('Jane','WorkplaceB','10-Jan-16','Worked') 

DECLARE @Name VARCHAR(100) = 'Jane' 
DECLARE @FromDate DATE = '01-Jan-16' 
DECLARE @ToDate DATE = '31-Jan-16'; 

WITH CTE 
AS (
    SELECT * 
     ,row_number() OVER (
      ORDER BY attndate 
      ) rn 
    FROM @t 
    WHERE NAME = @Name 
     AND (
      AttnDate BETWEEN @FromDate 
       AND @ToDate 
      ) 
    ) 
    ,CTE1 
AS (
    SELECT A.NAME 
     ,A.workplace 
     ,A.AttnDate 
     ,Shifts 
     ,rn 
     ,1 RN1 
    FROM cte A 
    WHERE rn = 1 

    UNION ALL 

    SELECT a.NAME 
     ,a.workplace 
     ,a.AttnDate 
     ,a.Shifts 
     ,CASE 
      WHEN a.workplace = b.workplace 
       THEN b.rn 
      ELSE b.rn + 1 
      END rn 
     ,RN1 + 1 
    FROM CTE A 
    INNER JOIN CTE1 b ON a.attndate > b.attndate 
    WHERE a.rn = RN1 + 1 
    ) 
    ,CTE2 
AS (
    SELECT NAME 
     ,Workplace 
     ,AttnDate beginDate 
     ,(
      SELECT max(AttnDate) 
      FROM CTE1 b 
      WHERE b.rn = a.rn 
      ) endDate 
     ,(
      SELECT count(*) 
      FROM CTE1 b 
      WHERE b.rn = a.rn 
       AND Shifts = 'Worked' 
      ) WorkShift 
     ,rn 
     ,ROW_NUMBER() OVER (
      PARTITION BY rn ORDER BY rn 
      ) rn3 
    FROM cte1 a 
    ) 
SELECT NAME 
    ,workplace 
    ,beginDate 
    ,endDate 
    ,WorkShift 
FROM cte2 
WHERE rn3 = 1