2015-10-17 4 views
-2

У меня есть таблица имеет эту структуруSQL Server Как создать группу внутри группы - Использование GROUP BY

enter image description here

EmployeeID | LogDate | LogTime | TerminalID | InOut | Accepted 

Эта таблица обрабатывать все лечащий из сотрудников

В тех случаях, когда колонка InOut = 0 -> In (работник просто наносит удар по его Shift)

Где Inout Колонка = 1 -> Out (Работник Только выбивать Чтобы закончить свою смену)

образец Дата, когда я оформлю Выбрать enter image description here

для примера предыдущее изображение имеет EmployeeID = 1009 имеют 2 ударов в 2015-10-14 (06:56:28) И (16:13:51) Мне нужно в результате, чтобы дать мне время, которое он посещает между этими двумя 2 Times что есть (09: 17:23)

Я хочу иметь эту структуру результата

EmployeeID | LogDate | NumberOfPunshings | State | HoursAttending 

Я попробовал этот запрос

 select 
Employeeid as EmpID, 
logdate as logdt, 
count(accepted) NumberOfPunshings, 
case count(accepted)     WHEN 1 THEN 'No Out Punch' 
              WHEN 2 THEN 'Perfect' 
              Else 'Null' 
              End as State, 
CONVERT(varchar(12), 
     DATEADD(minute, 
     DATEDIFF(minute, 
     (select top 1 LogTime from Accesslog where Inout=0), 
     (select top 1 LogTime from Accesslog where InOut=1)), 0), 114) as HoursAttending 

from Accesslog 
where Logdate = CAST('2015-10-14' AS datetime) 
group by 
employeeid,logdate 
order by Employeeid 

Но это не работает, как я хочу это только принять одно первое значение (из таблицы) в HoursAttending

enter image description here


Я Создать SQL Скрипки, чтобы показать вам, как данные он выглядит как

http://sqlfiddle.com/#!3/0152f9/1

EmpID |   logdt   | NumberOfPunshings | State | HoursAttending 

1009 | October, 14 2015 00:00:00 |   2   | Perfect | 08:00:00:000 
1088 | October, 15 2015 00:00:00 |   2   | Perfect | 08:00:00:000 

Ожидаемый результат должен быть

EmpID |   logdt   | NumberOfPunshings | State | HoursAttending 

1009 | October, 14 2015 00:00:00 |   2   | Perfect | 08:00:00:000 
1088 | October, 15 2015 00:00:00 |   2   | Perfect | 06:00:00:000 

Различия в этих таблицах в колонке HoursAttending, потому что

первый Сотрудник (1009) начинает работать с 08:00 до 16:00, так что продолжительность есть (8:00) Правильно.

Второй сотрудник (1088) начинает работать с 009: 00 до 15:00, поэтому продолжительность должна быть (06:00) нет (08:00) Исправить.

+1

что вы имеете в виду под 'не работает'? –

+0

@vkp i означает, что только HoursAttending Column. Возьмите одно значение в каждом столбце. я обновить сообщение с изображением результата – Loai

+0

Вы не ссылаетесь на EmpID в подзапросе – Horaciux

ответ

2

Представьте, что было бы возможно, если бы данные были легко доступны нам, и мы четко поняли, как должен выглядеть ожидаемый конечный результат.

SQL Fiddle

Сервер 2014 Настройка схемы MS SQL:

CREATE TABLE Accesslog 
    ([EmployeeID] int, [LogDate] datetime, [LogTime] datetime, [Terminal] varchar(11), [InOut] int, [Accepted] int) 
; 

INSERT INTO Accesslog 
    ([EmployeeID], [LogDate], [LogTime], [Terminal], [InOut], [Accepted]) 
VALUES 
    (1009, '2015-10-14 00:00:00', '1900-01-01 06:36:06', 'abcdedghijk', 0, 1), 
    (1009, '2015-10-14 00:00:00', '1900-01-01 16:22:41', 'abcdedghijk', 1, 1) 
; 

Запрос 1:

select 
     EmployeeID 
     , LogDate 
     , MIN(case when InOut = 0 then cast(LogTime as time) end) as LogTimeMin 
     , MAX(case when InOut = 1 then cast(LogTime as time) end) as LogTimeMax 
     , COUNT(*) as CountPunches 
     , CONVERT(varchar(12), 
     DATEADD(minute, 
     DATEDIFF(minute, 
     MIN(case when InOut = 0 then cast(LogTime as time) end), 
     MAX(case when InOut = 1 then cast(LogTime as time) end)), 0), 114) as HoursAttending 
from Accesslog 
group by 
     EmployeeID 
     , LogDate 

Results:

| EmployeeID |   LogDate | LogTimeMin | LogTimeMax | CountPunches | HoursAttending | 
|------------|------------------|-------------|-------------|--------------|----------------| 
|  1009 | October, 14 2015 | 06:36:06.00 | 16:22:41.00 |   2 | 09:46:00:000 | 

ЧАСТЬ 2

Для решения вопроса о сдвигах, пожалуйста, попробуйте следующее. Обратите внимание, если вы тогда хотите только одну строку в день, используйте группу по запросу, а также но сделать запрос показано ниже в «производной таблицы» (подзапрос)

SQL Fiddle

MS SQL Server 2014 Настройка схемы :

CREATE TABLE Accesslog 
    ([EmployeeID] int, [LogDate] datetime, [LogTime] datetime, [Terminal] varchar(11), [InOut] int, [Accepted] int) 
; 

INSERT INTO Accesslog 
    ([EmployeeID], [LogDate], [LogTime], [Terminal], [InOut], [Accepted]) 
VALUES 
    (1209, '2015-10-14 00:00:00', '1900-01-01 07:00:00', 'abcdedghijk', 0, 1), 
    (1209, '2015-10-14 00:00:00', '1900-01-01 12:01:00', 'abcdedghijk', 1, 1), 
    (1209, '2015-10-14 00:00:00', '1900-01-01 15:00:00', 'abcdedghijk', 0, 1), 
    (1209, '2015-10-14 00:00:00', '1900-01-01 20:02:00', 'abcdedghijk', 1, 1), 
    (1009, '2015-10-14 00:00:00', '1900-01-01 08:00:00', 'abcdedghijk', 0, 1), 
    (1009, '2015-10-14 00:00:00', '1900-01-01 16:00:00', 'abcdedghijk', 1, 1), 
    (1088, '2015-10-15 00:00:00', '1900-01-01 09:00:00', 'aaaa', 0, 1), 
    (1088, '2015-10-15 00:00:00', '1900-01-01 15:00:00', 'aaaa', 1, 1) 
; 

Запрос 1:

/* 
including (07:00 - 12:00) shift two (15:00 - 20:00) 
*/ 

WITH CTE as (
     SELECT *, ROW_NUMBER() OVER(PARTITION BY EmployeeID, LogDate, InOut 
            ORDER BY LogTime ASC) AS shiftno 
     FROM Accesslog 
      ) 
SELECT 
     ins.EmployeeID 
     , ins.LogDate 
     , ins.LogTime as LogTimeIn 
     , outs.LogTime as LogTimeOut 
     , ins.Accepted + ISNULL(outs.Accepted,0) as CountPunches 
     , CONVERT(varchar(12), 
     DATEADD(minute, 
     DATEDIFF(minute, 
     ins.LogTime, 
     outs.LogTime), 0), 114) as HoursAttending 
FROM CTE AS ins 
INNER JOIN CTE AS outs ON ins.InOut = 0 AND outs.InOut = 1 
         AND ins.EmployeeID = outs.EmployeeID 
         AND ins.LogDate = outs.LogDate 
         AND ins.shiftno = outs.shiftno 

Results:

| EmployeeID |     LogDate |     LogTimeIn |    LogTimeOut | CountPunches | HoursAttending | 
|------------|---------------------------|---------------------------|---------------------------|--------------|----------------| 
|  1009 | October, 14 2015 00:00:00 | January, 01 1900 08:00:00 | January, 01 1900 16:00:00 |   2 | 08:00:00:000 | 
|  1088 | October, 15 2015 00:00:00 | January, 01 1900 09:00:00 | January, 01 1900 15:00:00 |   2 | 06:00:00:000 | 
|  1209 | October, 14 2015 00:00:00 | January, 01 1900 07:00:00 | January, 01 1900 12:01:00 |   2 | 05:01:00:000 | 
|  1209 | October, 14 2015 00:00:00 | January, 01 1900 15:00:00 | January, 01 1900 20:02:00 |   2 | 05:02:00:000 | 
+0

Спасибо, я обновил сообщение, и вот SQL Fiddle http://sqlfiddle.com/#!3/0152f9/1 – Loai

+0

Отлично. Вы предоставили некоторые данные. Благодарю. Поскольку ожидаемый результат не был предоставлен, я не знаю, правильно ли я сделал это до сих пор. Поэтому, вместо того, чтобы угадать, чего вы ожидаете, я остановлюсь. –

+0

Спасибо, это то, что мне нужно Точно, теперь есть еще один вопрос в запросе, если вы не против – Loai