Рейтинг:
11
Wendelius
Из того, что я понял, ваш запрос в настоящее время вычисляет рабочее время для человека на каждый день. Поэтому, если вы хотите расширить логику для проверки сведений о сотрудниках, вы можете использовать встроенное представление.
Рассмотрим следующий пример
SELECT tt.EmpID,
tt.CalcDate,
DATEDIFF(Hour, tt.INtime, tt.OutTime) AS Hours,
CASE
WHEN DATEDIFF(Hour, tt.INtime, tt.OutTime) > 8
CASE ed.OTEntitled
WHEN 'Yes' THEN DATEDIFF(Hour, tt.INtime, tt.OutTime) - 8
ELSE 0
END
ELSE 0
END AS OverTime
FROM ( SELECT ma.EmpID,
CAST(ma.DateTime as date) AS CalcDate,
MAX(CASE WHEN ma.INOUT = 1 THEN ma.Datetime END) AS INtime,
MAX(CASE WHEN ma.INOUT = 2 THEN ma.Datetime END) AS Outtime
FROM MachineAttendance ma
GROUP BY ma.EmpID,
CAST(ma.DateTime as date)) tt
INNER JOIN EmployeeDetails ed ON ed.EmpID = tt.EmpID;
Maciej Los
По-моему, выглядит идеально!
Member 12314309
@Венделиус...
Пожалуйста, посмотрите на мой запрос, дающий ошибку Msg 4104, Уровень 16, состояние 1, строка 3
Многосоставный идентификатор "EmployeeDetails.Эмпид" не мог быть связан.
;С cte1 в качестве
(
Выберите EmployeeDetails.EmpID, CAST([Date] as Date) AS [Date],
Случай, когда INOUT = 1, то [дата] заканчивается как INTIME,
Случай, когда INOUT = 2, то [дата] заканчивается как OUTTIME
От MachineAttendance
), cte2 как
(
выберите EmployeeDetails.Empid В, [MachineAttendance.Дата], максимум(Интайм) как Интайм, Макс(OUTTIME) как OUTTIME
, Функция datediff(час, максимум(Интайм), Макс(OUTTIME)) как [Ч]
ОТ CTE1
Группировка по EmployeeDetails. Empid В, [MachineAttendance.Дата]
)
выберите EmployeeDetails.Empid В, [MachineAttendance.Дата], INTIME, OUTTIME, [часы]
, Случай, когда [часы] >= 8, то 1
Когда [часы] = 0, ТО 0
Когда [часы] >= 6, то 0,5 заканчиваются как [День],
Случай, когда [часы] > 8, то [часы] - 8 else 0 End as OT,
Случай, когда [часы] >= 8
затем ([часы] - 8) * 100 else 0 END AS OTAMount,
Преобразование(varchar(10),MachineAttendance.Дата,120) как [дата],
Конвертировать(varchar(10),INTIME,108) в [Time],
Случай, когда Convert(Time,INTIME,108) > '09:10', ТО 1 else 0 end as Late
от cte2
Внутреннее соединение EmployeeDetails на EmployeeDetails.Empid в=MachineAttendance.Empid в
Wendelius
Глядя на следующий запрос в CTE
SELECT EmployeeDetails.EmpID, CAST([Date] as Date) AS [Date],
CASE WHEN INOUT = 1 THEN [Date] END AS INTIME,
CASE WHEN INOUT = 2 THEN [Date] END AS OUTTIME
FROM MachineAttendance
Вы не смотрите
EmployeeDetails
таблица в предложении FROM, но вы пытаетесь извлечь из нее столбец в предложении SELECT.
Таким образом, в основном вам нужно либо добавить EmployeeDetails в предложение FROM, либо изменить предложение SELECT. Поскольку вы еще не опубликовали структуру таблицы, трудно сказать, какая из них правильная.
Но если у вас есть EmpId в MachineAttendance, то следующее должно быть правильным
SELECT ma.EmpID,
CAST(ma.[Date] as Date) AS [Date],
CASE WHEN INOUT = 1 THEN ma.[Date] END AS INTIME,
CASE WHEN INOUT = 2 THEN ma.[Date] END AS OUTTIME
FROM MachineAttendance ma
Несколько замечаний, почему вы ставите дату на дату? если все правильно, то тип данных уже должен быть датой. Другое дело, что вы должны избегать использования зарезервированных слов, таких как дата. Использование их очень легко порождает ненужные ошибки
Member 12314309
Empid-это FK в MachineAttendance и ссылка из таблицы employee, а Date-col of Machineattendance
Wendelius
Не уверен, что вы имели в виду комментарий как вопрос, но если запрос все еще вызывает проблемы, я предлагаю создавать его по частям.
Например, первый, где вы выбираете посещаемость. Попробуйте что - нибудь вроде
;WITH Attendances AS (
SELECT ma.EmpID,
[Date] AS AttendanceDate,
CASE WHEN INOUT = 1 THEN [Date] END AS INTIME,
CASE WHEN INOUT = 2 THEN [Date] END AS OUTTIME
FROM MachineAttendance ma
)
SELECT * FROM Attendances;
Если это даст ожидаемые результаты, переходите к следующему этапу
;WITH Attendances AS (
SELECT ma.EmpID,
[Date] AS AttendanceDate,
CASE WHEN INOUT = 1 THEN [Date] END AS INTIME,
CASE WHEN INOUT = 2 THEN [Date] END AS OUTTIME
FROM MachineAttendance ma
), DailyHours AS (
SELECT a.EmpId,
a.AttendanceDate,
MAX(a.INTIME) AS INTIME,
MAX(a.OUTTIME) AS OUTTIME,
DATEDIFF(Hour, MAX(a.INTIME), MAX(a.OUTTIME)) as AttendanceHours
FROM Attendances
GROUP BY a.EmpId,
a.AttendanceDate
)
SELECT * FROM DailyHours;
Опять же если результаты верны то следующим может быть
;WITH Attendances AS (
SELECT ma.EmpID,
[Date] AS AttendanceDate,
CASE WHEN INOUT = 1 THEN [Date] END AS INTIME,
CASE WHEN INOUT = 2 THEN [Date] END AS OUTTIME
FROM MachineAttendance ma
), DailyHours AS (
SELECT a.EmpId,
a.AttendanceDate,
MAX(a.INTIME) AS INTIME,
MAX(a.OUTTIME) AS OUTTIME,
DATEDIFF(Hour, MAX(a.INTIME), MAX(a.OUTTIME)) as AttendanceHours
FROM Attendances
GROUP BY a.EmpId,
a.AttendanceDate
)
SELECT dh.EmpID,
dh.AttendanceDate,
dh.INTIME,
dh.OUTTIME,
dh.AttendanceHours,
CASE WHEN dh.AttendanceHours >= 8 THEN 1
WHEN dh.AttendanceHours = 0 THEN 0
WHEN dh.AttendanceHours >= 6 THEN 0.5
END AS DailyFactor,
WHEN DATEDIFF(Hour, dh.INtime, dh.OutTime) > 8
CASE ed.OTEntitled
WHEN 'Yes' THEN DATEDIFF(Hour, dh.INtime, dh.OutTime) - 8
ELSE 0
END
ELSE 0
END AS OverTime
FROM DailyHours dh
INNER JOIN EmployeeDetails ed ON ed.EmpID = dh.EmpID:
Member 12314309
@Wendelius большое спасибо за то,что дал мне новый путь для изучения sql-команды, еще раз спасибо ,если вы не возражаете, можете ли вы поделиться skype id, мой skype id-akhter.hussain80
Wendelius
Рад, что это помогло!
К сожалению, я не пользуюсь Скайпом. Кроме того, если вы столкнетесь с какими-либо проблемами в кодировании, я считаю, что лучше всего разместить вопрос в CodeProject. Таким образом, вы получаете качественную помощь от всех профессионалов на сайте.
Member 12314309
хорошо спасибо