akhter86 Ответов: 1

Как рассчитать сверхурочную работу и сумму в SQL


У меня есть два стола

Главная таблица сотрудников и еще одна таблица посещаемости сотрудников

Нет у меня есть расчет часов и суток на основе времени входа и выхода ,
Теперь я хочу рассчитать сверхурочные часы из часов(часы-8 часов(стандартные часы)),сверхурочные будут рассчитываться, то я хочу добавить условие, что если сотруднику разрешено пользоваться сверхурочными, то сверхурочные сотрудника будут рассчитываться иначе, а не вычисляться.Например (Сверхурочная Работа * 100(Ставка Сверхурочной Работы).

If Hours =0 then their OT will be =0 but value are coming in minus.


Что я уже пробовал:

SELECT Empcode,cast(Date as date) As [Date],
   MIN(CASE WHEN INOUT = 1 THEN date END) AS INOUT_INTIME,
   MAX(CASE WHEN INOUT = 2 THEN date END) AS INOUT_OutTime,
   DATEDIFF(Hour ,MIN(Date),Max(Date)) AS [Hours],
   case when DATEDIFF(Hour ,MIN(Date),Max(Date)) >= 8 Then 1  
        when DATEDIFF(Hour ,MIN(Date),Max(Date))  = 0 then 0 
         when DATEDIFF(Hour ,MIN(Date),Max(Date))  >=6 then 0.5 
        end as [Day],
           Case when DATEDIFF(Hour ,MIN(Date),Max(Date))-8 and end
         as [OT],
     
   FROM HR2 AS t
   GROUP BY Empcode,CONVERT(date, date);

#realJSOP

Один из ваших одноклассников задал этот вопрос пару недель назад.

akhter86

Lolz,,,спасибо за комментарий

Richard MacCutchan

В чем же вопрос?

CHill60

Предоставьте некоторые примеры данных и ваши ожидаемые результаты. Тогда объясните, в чем проблема.
Используйте ссылку улучшить вопрос для добавления информации к вашему вопросу

akhter86

@Chill60 я пытался определить вас ,если у вас есть какие-либо вопросы, пожалуйста, спросите

CHill60

Ваш вопрос все еще не прояснился. Дайте нам некоторые примеры данных - данные, которые вы используете, и результаты, которые вы ожидаете. Только тогда я смогу понять, почему мое решение работает для меня, но не для вас.
Вы также должны обновить свой вопрос с помощью кода, который вы сейчас используете.

1 Ответов

Рейтинг:
8

CHill60

Эта часть вашего запроса

Case when DATEDIFF(Hour ,MIN(Date),Max(Date))-8 and end
         as [OT],
это еще не конец. Но в этом нет необходимости. CASE, просто рассчитайте сверхурочные.

Ваша следующая проблема заключается в том, что вы пытаетесь сделать все сразу, разбить его так, чтобы вы могли видеть, что на самом деле происходит.

Например я использовал этот пример данных
DECLARE @HR2 AS TABLE (Empcode INT, [Date] datetime, INOUT INT)
INSERT INTO @HR2 (Empcode, [Date], INOUT) VALUES
(1, '2018-12-03 09:00:00', 1),
(1, '2018-12-03 18:00:00', 2),
(1, '2018-12-04 09:00:00', 1),
(1, '2018-12-04 17:00:00', 2)
Если я выполню этот запрос …
SELECT Empcode, CAST([Date] as Date) AS [Date],
CASE WHEN INOUT = 1 THEN [Date] END AS INOUT_INTIME,
CASE WHEN INOUT = 2 THEN [Date] END AS INOUT_OUTTIME
FROM @HR2
Я получаю следующие результаты
  Date		INTIME			OUTTIME
1 2018-12-03	2018-12-03 09:00:00.000	NULL
1 2018-12-03	NULL			2018-12-03 18:00:00.000
1 2018-12-04	2018-12-04 09:00:00.000	NULL
1 2018-12-04	NULL			2018-12-04 17:00:00.000
Теперь я могу сделать свой MIN/MAX и т. д. На этом подзапросе
select Empcode, [Date], MAX(INOUT_INTIME) AS INOUT_TIME, MAX(INOUT_OUTTIME) AS INOUT_TIME
FROM
(
	SELECT Empcode, CAST([Date] as Date) AS [Date],
	CASE WHEN INOUT = 1 THEN [Date] END AS INOUT_INTIME,
	CASE WHEN INOUT = 2 THEN [Date] END AS INOUT_OUTTIME
	FROM @HR2
) SubQury
GROUP BY Empcode, [Date]
Что меняет мои результаты так, чтобы они выглядели
  Date		INTIME			OUTTIME
1 2018-12-03	2018-12-03 09:00:00.000	2018-12-03 18:00:00.000
1 2018-12-04	2018-12-04 09:00:00.000	2018-12-04 17:00:00.000
Я мог бы добавить и все остальное
, DATEDIFF(Hour, MAX(INOUT_INTIME), MAX(INOUT_OUTTIME)) as Hours
, CASE WHEN DATEDIFF(Hour, MAX(INOUT_INTIME), MAX(INOUT_OUTTIME)) >= 8 THEN 1
	WHEN DATEDIFF(Hour, MAX(INOUT_INTIME), MAX(INOUT_OUTTIME)) = 0 THEN 0
	WHEN DATEDIFF(Hour, MAX(INOUT_INTIME), MAX(INOUT_OUTTIME)) >= 6 THEN 0.5 END AS [Day],
	DATEDIFF(Hour, MAX(INOUT_INTIME), MAX(INOUT_OUTTIME)) - 8 as OT
Но это начинает выглядеть некрасиво, и я делаю один и тот же расчет 4 раза, что не очень эффективно. Я предпочитаю использовать общие табличные выражения ... например, такие …
;WITH cte1 AS
(
	SELECT Empcode, CAST([Date] as Date) AS [Date],
	CASE WHEN INOUT = 1 THEN [Date] END AS INOUT_INTIME,
	CASE WHEN INOUT = 2 THEN [Date] END AS INOUT_OUTTIME
	FROM @HR2
), cte2 as
(
	select Empcode, [Date], MAX(INOUT_INTIME) AS INTIME, MAX(INOUT_OUTTIME) AS OUTTIME
	, DATEDIFF(Hour, MAX(INOUT_INTIME), MAX(INOUT_OUTTIME)) as [Hours]
	FROM CTE1
	GROUP BY Empcode, [Date]
)
select Empcode, [Date], INTIME, OUTTIME, [Hours]
, CASE WHEN [Hours] >= 8 THEN 1
	WHEN [Hours] = 0 THEN 0
	WHEN [Hours] >= 6 THEN 0.5 END AS [Day],
[Hours] - 8 as OT
from cte2
Теперь вам нужно посмотреть на свой расчет [дня] ... в основном вы говорите, что если кто-то работает 8 или более часов, то он работал 1 день. Если кто-то вообще не проработал ни одного часа, то он проработал 0 дней. Но им приписывают работу только на полдня, если они работают больше 6 часов?

Звучит немного несправедливо по отношению к парням, которые проработали 4 или более часов ... то есть половину стандартного дня :смейтесь:


Wendelius

Приятно!

Maciej Los

Ух ты!
Кэролайн, ты заслуживаешь нового ника: SqlPedia (Sql + encyclopedia) ;)
5ed!

CHill60

Лол! Спасибо Мацей

akhter86

Спасибо за обмен КТР