2017-06-23 50 views
0

我有3個表 1.日曆日期 2.員工詳細 3.衝牀計時 以下表中我需要生成報表來回回月出勤需要SQL SELECT查詢員工的月出勤報告

date 
2017-06-01 
2017-06-02 
2017-06-03 
2017-06-04 
2017-06-05 
2017-06-06 
2017-06-07 
2017-06-08 
2017-06-09 
2017-06-10 
2017-06-11 
2017-06-12 
2017-06-13 
2017-06-14 
2017-06-15 


pk EmployeeName 
3 IMMAM 
4 SRIMAN 
5 AJAY 
6 Vinay 
7 RAGHU 

3.衝牀計時

EmployeePk PunchTime 
4 2017-06-10 17:49:34.000 
4 2017-06-10 18:51:35.000 
7 2017-06-10 19:18:37.000 
6 2017-06-10 19:18:52.000 
5 2017-06-10 19:19:05.000 
6 2017-06-12 10:59:34.000 
5 2017-06-12 10:59:44.000 
5 2017-06-12 16:04:24.000 
6 2017-06-12 16:06:48.000 
5 2017-06-12 16:08:58.000 
5 2017-06-12 16:14:33.000 
5 2017-06-13 10:44:06.000 
6 2017-06-13 10:44:23.000 
4 2017-06-13 10:44:36.000 
7 2017-06-13 10:51:22.000 
5 2017-06-13 17:45:59.000 
6 2017-06-13 17:46:14.000 
7 2017-06-13 17:46:26.000 
4 2017-06-13 17:47:21.000 
5 2017-06-14 10:48:39.000 
6 2017-06-14 10:49:04.000 
7 2017-06-14 10:49:16.000 
4 2017-06-14 10:49:23.000 
6 2017-06-14 17:22:34.000 
7 2017-06-14 18:23:08.000 
4 2017-06-14 18:23:25.000 
5 2017-06-14 18:23:32.000 
5 2017-06-15 10:44:48.000 
4 2017-06-15 10:45:13.000 
6 2017-06-15 10:45:32.000 
7 2017-06-15 11:03:55.000 
5 2017-06-15 11:26:53.000 
7 2017-06-15 11:26:56.000 
5 2017-06-15 11:29:16.000 
5 2017-06-15 11:29:20.000 

我需要的報告類似

Calender Date Employee Punchtime IsPresent 
10-06-2017 Imama Null No 
10-06-2017 SRIMAN 2017-06-10 17:49:34.000 Yes 
10-06-2017 AJAY 2017-06-10 19:19:05.000 Yes 
10-06-2017 Vinay 2017-06-10 19:18:52.000 Yes 
10-06-2017 RAGHU 2017-06-10 19:18:37.000 Yes 
11-06-2017 Imama Null NO 
11-06-2017 SRIMAN Null NO 
11-06-2017 AJAY Null NO 
11-06-2017 Vinay Null NO 
11-06-2017 RAGHU Null NO 
12-06-2017 Imama Null No 
12-06-2017 SRIMAN Null No 
12-06-2017 AJAY 2017-06-12 10:59:44.000 Yes 
12-06-2017 Vinay 2017-06-12 10:59:34.000 Yes 
12-06-2017 RAGHU 2017-06-12 10:59:44.000 Yes 

而且洙

我開始與像這樣

declare 
@month int, @year int, @lastDay int, 
@starttime datetime, 
@endtime datetime, 
@companyPk int, 
@employeePk int 

set @starttime ='2017-06-01' 
set @endtime = '2017-06-30' 
set @companyPk =2 
set @employeePk =0 

select x.calenderdate,y.Pk,y.EmployeeName,y.Ispresent 

from 
(

(select convert(date, CalendarDate) as calenderdate from ECMSCalendar 
where convert(date, CalendarDate) >= @starttime and convert(date, CalendarDate) <[email protected] 
) as x 
left join 
(
select a.Pk,a.EmployeeName,(case when b.IsPresent is null then 'Absent' else b.IsPresent end) as Ispresent from 
(
(select emp.Pk,emp.EmployeeName from EmployeeDetails emp where emp.Companypk = @companyPk) as a 
left join 
(SELECT ed.pk as Pk,ed.EmployeeName as StaffName , 

(case when (DATEDIFF(MINUTE,min(bio.PunchTime),(case when max(bio.PunchTime) = min(bio.PunchTime) then min(bio.PunchTime) else max(bio.PunchTime) end))) < sd.shiftname then 'Absent' else 'Present' end) as IsPresent 

--, CONVERT(nvarchar(2), bio.PunchTime) as date 
--,count(CONVERT(nvarchar(2), bio.punchtime, 103))as day 

from BioMetricPunchDetails bio 
left join EmployeeDetails ed on ed.Pk = bio.EmployeePk 
left join EmployeeShiftDetails esd on esd.EmployeePk = ed.pk 
left join ShiftDetails sd on sd.pk =esd.shiftpk 
where --convert (date,bio.punchtime) >= @starttime and convert (date,bio.punchtime) <= @endtime 
convert (date,(select min(bpd.PunchTime) from BioMetricPunchDetails bpd where ([email protected] or @employeePk=0))) >= @starttime and convert (date,(select max(bpd.PunchTime) from BioMetricPunchDetails bpd where ([email protected] or @employeePk=0))) <= @endtime 
and 
ed.Companypk= @companyPk and ([email protected] or @employeePk=0) 
--and [email protected] 
group by ed.pk, ed.EmployeeName,sd.shiftname) as b 
on a.Pk = b.Pk) 
) as y 
on x.calenderdate = y.Ispresent 
) 
order by x.calenderdate 

請解決該任務謝謝

+1

太棒了!你應該從'SELECT'開始。 –

+0

看看'LEFT JOIN'的功能。 – ZLK

+0

似乎太複雜了...格式化您的查詢也會有很大幫助。 –

回答

0

嘗試這樣的事情

with 
alldates as (
SELECT convert(date,thedate) alldate 
FROM dbo.ExplodeDates('2017-06-10' , '2017-06-10') as d 
), 

empshift as (
select ed.Pk,ed.EmployeeName,sd.ShiftName,sd.Intime,sd.OutTime from EmployeeDetails ed left outer join 
EmployeeShiftDetails esd on (ed.Pk = esd.EmployeePk) 
left outer join ShiftDetails sd on (sd.Pk = esd.ShiftPk) 
) 
,biometric1 as (
select min(punchtime) intime,max(punchtime) outtime,convert(date,punchtime) dates 

, empshift.EmployeeName,empshift.ShiftName,Intime ShiftInTime,OutTime ShiftOutTime 
from BioMetricPunchDetails bpd inner join empshift on (empshift.Pk =bpd.EmployeePk) 

where CONVERT(date,punchtime) between '2017-06-10' and '2017-06-0' 

group by convert(date,punchtime), empshift.EmployeeName,empshift.ShiftName,Intime,OutTime 
), 

fnl as (
select convert(date,intime) dates,intime, 
case when (intime = outtime) then NULL else outtime end as outtime 
,ShiftName,DATEDIFF(MINUTE,intime,outtime) duration,ShiftInTime,convert(time,intime) InTimeHrMin 
,datediff(MINUTE,ShiftInTime, convert(time,intime)) lateby 
from biometric1 
), 

fnl1 as (select * from alldates left outer join fnl 
on (alldates.alldate = fnl.dates)) 

select ed.EmployeeName,fnl1.* from EmployeeDetails ed cross join fnl1 
+0

謝謝,我會盡力回覆它很全用 –

0

報告都不錯。他們進入整潔的小電子郵件或PowerPoint 演示文稿,沒有人真正關注,但他們肯定會讓我們覺得我們很有成效。

1)您是否試圖跟蹤每月 會議中缺少哪些缺省值?

  • 你的會議出了什麼問題?他們有沒有收穫?他們是否真的提供了外出或IM(如Skype,微軟團隊,Slack)不能提供的團隊之間的凝聚力?

2)您是否試圖查看誰正忙着來參加會議?

  • 打孔至少表明他們在那裏......但他們參與?增值?
  • 當然,還有其他指標可以用來發現員工的職業道德。

讓您的報告回答的問題,一個簡單的查詢不能。避免報道會填滿空間的誘惑。

但是,您的業務記錄會議的軌道,一定要以表格形式獲取日期。

CREATE TABLE #Calendar_Date (DATES Date) 
INSERT INTO #Calendar_Date 
VALUES ('2017-06-01'),('2017-06-02'),('2017-06-03'),('2017-06-04'),('2017-06-05'),('2017-06-06'),('2017-06-07'),('2017-06-08'),('2017-06-09'),('2017-06-10'),('2017-06-11'),('2017-06-12'),('2017-06-13'),('2017-06-14'),('2017-06-15') 

CREATE TABLE #Employee_DIM (ID INT UNIQUE 
         , Employee_Name NVARCHAR(100)) 
INSERT INTO #Employee_DIM (ID, Employee_Name) 
VALUES (3, 'IMMAM'), (4, 'SRIMAN'), (5, 'AJAY'), (6, 'Vinay'), (7, 'RAGHU') 

CREATE TABLE #Punch_Timings (Employee_PK INT 
          , Punch_Time DATETIME) 

INSERT INTO #Punch_Timings (Employee_PK, Punch_Time) 
VALUES (4,'2017-06-10 17:49:34.000'),(4,'2017-06-10 18:51:35.000'),(7,'2017-06-10 19:18:37.000') 
     ,(6,'2017-06-10 19:18:52.000'),(5,'2017-06-10 19:19:05.000'),(6,'2017-06-12 10:59:34.000') 
     ,(5,'2017-06-12 10:59:44.000'),(5,'2017-06-12 16:04:24.000'),(6,'2017-06-12 16:06:48.000') 
     ,(5,'2017-06-12 16:08:58.000'),(5,'2017-06-12 16:14:33.000'),(5,'2017-06-13 10:44:06.000') 
     ,(6,'2017-06-13 10:44:23.000'),(4,'2017-06-13 10:44:36.000'),(7,'2017-06-13 10:51:22.000') 
     ,(5,'2017-06-13 17:45:59.000'),(6,'2017-06-13 17:46:14.000'),(7,'2017-06-13 17:46:26.000') 
     ,(4,'2017-06-13 17:47:21.000'),(5,'2017-06-14 10:48:39.000'),(6,'2017-06-14 10:49:04.000') 
     ,(7,'2017-06-14 10:49:16.000'),(4,'2017-06-14 10:49:23.000'),(6,'2017-06-14 17:22:34.000') 
     ,(7,'2017-06-14 18:23:08.000'),(4,'2017-06-14 18:23:25.000'),(5,'2017-06-14 18:23:32.000') 
     ,(4,'2017-06-15 10:45:13.000'),(6,'2017-06-15 10:45:32.000'),(7,'2017-06-15 11:03:55.000') 
     ,(5,'2017-06-15 11:26:53.000'),(7,'2017-06-15 11:26:56.000'),(5,'2017-06-15 11:29:16.000') 
     ,(5,'2017-06-15 11:29:20.000'),(4, '2017-06-10 19:31:35.000'),(5, '2017-06-10 19:45:05.000') 
     ,(6, '2017-06-10 19:38:52.000'),(7, '2017-06-10 19:13:37.000') 

CREATE TABLE #MEETING_TIMES (Meeting_ID INT 
          , Meeting_Start DATETIME 
          , Meeting_End DATETIME) 
INSERT INTO #MEETING_TIMES (Meeting_ID, Meeting_Start, Meeting_End) 
VALUES (304,'2017-06-10 19:00:00.000', '2017-06-10 19:30:00.000') 
    , (311, '2017-06-14 18:00:00.000', '2017-06-14 18:30:00.000') 

一旦你有你的尺寸,並以有序的方式事實,邏輯應該是這樣非常簡單以下幾點:

;WITH Employee_Time AS (
SELECT MIN(Punch_Time) AS ASSUME_Punch_IN 
    , MAX(PUNCH_Time) AS ASSUME_Punch_OUT 
    , DATEPART(DAY, Punch_Time) AS DAY 
    , Employee_PK 
FROM #Punch_Timings PT 
GROUP BY Employee_PK, DATEPART(DAY, Punch_Time) 
) 

SELECT B.Meeting_ID 
    , A.Meeting_Start 
    , Employee_ID 
    , CASE WHEN A.Meeting_Start IS NULL THEN 'NO' ELSE 'YES' END AS FLAG_ATTEND 
FROM (SELECT ET.Employee_PK, ET.ASSUME_Punch_IN 
      , ET.ASSUME_Punch_OUT, ET.DAY, MT.Meeting_Start, MT.Meeting_End 
     FROM Employee_Time ET 
     INNER JOIN #MEETING_TIMES MT ON (( ET.ASSUME_Punch_IN >= MT.Meeting_Start 
             AND ET.ASSUME_Punch_IN < MT.Meeting_End) 
            OR ( ET.ASSUME_Punch_IN <= Meeting_Start 
             AND ET.ASSUME_Punch_OUT > Meeting_Start) 
            ) 
           AND ET.DAY = DATEPART(DAY, Meeting_Start) 
      ) A 
RiGHT OUTER JOIN ( 
        SELECT ID AS Employee_ID, Meeting_Start, Meeting_ID 
        FROM #MEETING_TIMES B  
        FULL JOIN #Employee_DIM ED ON 1=1 
        ) B ON B.Employee_ID = A.Employee_PK 
         AND DATEPART(DAY, B.Meeting_Start) = A.DAY 

這就是說,我會從這個這樣找到其他信息作爲緊迫性和你的同事的項目性質。在數據中找不到問題並讓您的報告回答這個問題。

+0

順便說一下,第一個問題的答案是3. :) –

+0

用於匹配會議與Punch_Times的邏輯是'IF PUNCH_IN> =會議開始 \t AND IF PUNCH_IN <會議結束 否則如果PUNCH_IN <=會議開始 \t和PUNCH_OUT>會議開始 –