#sql #sql-server-2008
#sql #sql-server-2008
Вопрос:
У меня есть 2 таблицы, 1 — это EMployeeMaster, а другая — посещаемость
***EmployeeMaster***
EmployeeId EmployeeName DepartmentId
1 ABC 1
2 XYZ 2
3 PQR 2
4 WXY 1
Теперь у меня есть другая таблица посещаемости
***Attendance***
AttendanceId EmployeeId Date InTime OutTime
1 1 2011-04-04 00:00:00 10:00 AM 6:30 PM
2 2 2011-04-04 00:00:00 09:45 AM 7:10 PM
Как только сотрудник заходит в офис и нажимает пальцем на устройство, его запись переходит в таблицу посещаемости с указанием InTime, EmployeeID и даты.
Таким образом, сотрудник, который не пришел в офис, его запись не будет существовать в таблице посещаемости.
Теперь я хочу сгенерировать ежедневный отчет..В нем должна отображаться посещаемость всех сотрудников компании вместе с их временем работы по дате. Все отсутствующие сотрудники также должны отображаться в этом отчете.
Итак, я хочу :
EmployeeId EMployeeName DepartmentId Date InTime OutTime
1 ABC 1 2011-04-04 00:00:00 10:00 AM 6:30 PM
2 XYZ 2 2011-04-04 00:00:00 09:45 AM 7:10 PM
3 PQR 2 NULL/- NULL/- NULL/-
4 WXY 1 NULL/- NULL/- NULL/-
Можете ли вы сказать мне, каким должен быть запрос???
Ответ №1:
Вы должны использовать левое внешнее соединение.
declare @E table (EmployeeId int, EmployeeName varchar(50), DepartmentId int)
declare @A table (AttendanceId int, EmployeeId int, [Date] date, InTime time, OutTime time)
insert into @E values
(1, 'ABC', 1),
(2, 'XYZ', 2),
(3, 'PQR', 2),
(4, 'WXY', 1)
insert into @A values
(1, 1, '2011-04-04 00:00:00', '10:00 AM', '6:30 PM'),
(2, 2, '2011-04-04 00:00:00', '09:45 AM', '7:10 PM')
select
E.EmployeeId,
E.EmployeeName,
E.DepartmentId,
A.[Date],
A.InTime,
A.OutTime
from @E as E
left outer join @A as A
on E.EmployeeId = A.EmployeeId and
A.[Date] = '2011-04-04 00:00:00'
Результат
EmployeeId EmployeeName DepartmentId Date InTime OutTime
----------- -------------------------------------------------- ------------ ---------- ---------------- ----------------
1 ABC 1 2011-04-04 10:00:00.0000000 18:30:00.0000000
2 XYZ 2 2011-04-04 09:45:00.0000000 19:10:00.0000000
3 PQR 2 NULL NULL NULL
4 WXY 1 NULL NULL NULL
Редактировать 1
Если вам нужно сделать это в течение одного месяца, я бы использовал какую-нибудь таблицу чисел или таблицу календаря. Здесь я использовал cte для построения календаря, используя @FromDate и @ToDate
declare @E table (EmployeeId int, EmployeeName varchar(15), DepartmentId int)
declare @A table (AttendanceId int, EmployeeId int, [Date] date, InTime time, OutTime time)
insert into @E values
(1, 'ABC', 1),
(2, 'XYZ', 2),
(3, 'PQR', 2),
(4, 'WXY', 1)
insert into @A values
(1, 1, '2011-04-02', '04:00 AM', '4:30 PM'),
(2, 2, '2011-04-02', '05:00 AM', '5:30 PM'),
(3, 1, '2011-04-03', '06:00 AM', '6:30 PM'),
(4, 2, '2011-04-03', '07:00 AM', '7:30 PM'),
(5, 1, '2011-04-04', '08:00 AM', '8:30 PM'),
(6, 2, '2011-04-05', '09:00 AM', '9:10 PM')
-- Set FromDate to first day of month
declare @FromDate date = '20110401'
-- Set ToDate to last day of month
declare @ToDate date = '20110405'
-- Create cte with all dates between FromDate and ToDate
;with cteCal as
(
select @FromDate as [Date]
union all
select dateadd(d, 1, [Date]) as [Date]
from cteCal
where [Date] < @ToDate
)
select
E.EmployeeId,
E.EmployeeName,
E.DepartmentId,
C.[Date],
A.InTime,
A.OutTime
from cteCal as C
cross join @E as E
left outer join @A as A
on E.EmployeeId = A.EmployeeId and
C.[Date] = A.[Date]
order by C.[Date], E.EmployeeName
option (maxrecursion 0)
Комментарии:
1. @Kishan — Не в предложении where, в join. Обновленный ответ.
2. У меня возникла 1 проблема .. надеюсь, вы сможете помочь me…in текущий сценарий, когда я получу ежемесячный отчет … я не узнаю, на какую дату кто отсутствует… Итак, есть ли какой-либо способ, которым я могу этого добиться…
3. @Kishan — обновленный ответ. Вероятно, это должно было быть в другом вопросе, чтобы вы могли получить больше предложений о том, как это сделать, чем мои.
Ответ №2:
Должно выглядеть так:
select
EmployeeId,
EmployeeName,
DepartmentId,
Date,
InTime,
OutTime
from EmployeeMaster em
left join Attendance a on em.EmployeeId=a.EmployeeId and Date='2011-04-04 00:00:00'
Комментарии:
1. Не удается получить отсутствующих сотрудников .. ПОЭТОМУ EmployeeID-3 и 4 не отображаются в результате….
2. ОК.. вы должны получить их сейчас
Ответ №3:
select E.EmloyeeId, EmployeeName, DepartmentId, Date, InTime, OutTime
from EmployeeMaster as e
LEFT JOIN Attendance as a ON a.EmloyeeId = e.EmloyeeId
Комментарии:
1. Посмотрите, как это работает… но когда я передаю определенную дату, я не получаю отсутствующих сотрудников…
select E.EmployeeId, EmployeeName, DepartmentId, Date, InTime, OutTime from EmployeeMaster as e LEFT JOIN Attendance as a ON a.EmployeeId = e.EmployeeId where a.Date='2011-04-04'