2014-06-23 1 views
1

В sql-запросе я пытаюсь сделать две вещи.Использование XML PATH для управления данными строки при группировке

У меня есть таблица Attendance как этот

ТАБЛИЦА

EID | PID |  In_Time  |  Out_Time  | Shift 
__________________________________________________________ 
100 | S001 | 2014-05-01 07:10 | 2014-05-01 19:20 | D 
100 | S001 | 2014-05-04 07:00 | 2014-05-04 19:00 | D 
100 | S001 | 2014-05-04 19:00 | 2014-05-05 07:00 | N 

ВИЗ -EmployeeID

PID -PointID (Location)

D - день Сдвиг

N - Night Shift

Когда (будет принято При группировке только DatePart из In_Time полей) I группы по всем полям, кроме смены, я хочу, чтобы получить эту

Промежуточным этапом

EID | DAY | Shift | 
___________________ 
100 | 01 | D | 
100 | 04 | D/N | 

И наконец, я хочу PIVOT это, чтобы получить следующий результат

ОЖИДАЕМЫЕ РЕЗУЛЬТАТЫ ФИНАЛ

EmployeeID | 01 | 02 | 03 | 04 | 
__________________________________ 
100  | D | _ | _ | D/N | 

Я использую следующий запрос в этой цели, но я получаю немного другой результат.

SELECT EID AS EmployeeID, [1],[2],[3],[4] 
FROM (

SELECT 
    EID, datepart(dd,in_time) as [DAY], 
    STUFF((
    SELECT '/ ' + Shift 
    FROM Attendance 
    WHERE ([in_time] = Results.[in_time]) 
    FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)') 
    ,1,2,'') AS Shifts 
FROM Attendance Results 
WHERE EID = '100' AND PID ='C002' 
GROUP BY EID , in_time 
) AS SourceTable 

PIVOT 
(
MAX (Shifts) 
FOR [DAY] IN ([1],[2],[3],[4]) 
) AS PivotTable 

Это результат запроса

EmployeeID | 01 | 02 | 03 | 04 | 
    ________________________________ 
    100  | D | _ | _ | N/N | 

Так что-то не так в моем запросе, и вы могли бы мольбы помочь мне разобраться в этом? Что мне не хватает в этом запросе? Вы знаете лучший способ сделать это?

EDIT: Я просто понял, что приведенный выше код работает хорошо, если таблица посещаемости содержит записи, относящиеся к одному сотруднику и одной точке (PID).

Если приведенная выше таблица содержит сведения о нескольких сотрудниках (EID), которые работают в разных местах (PID), тогда неправильный вариант. Таким образом, я вижу, что код не является согласованным, но моих знаний в sql кажется недостаточно, чтобы разобраться в этом без помощи :(

+0

Как насчет Out_Time = 2014-05-05 07:00. Он не отображается в вашем желаемом результате. Неужели вы смотрели только на время работы рабочего дня? –

+0

@ Jithin Shaji, Да, сдвиг относится к дню In_Time. Поэтому я не хочу получать Out_Time. Out_Time будет использоваться только для категоризации сдвигов. – Deva

+0

Я удалил ненужные вещи, чтобы сделать его более простым. – Deva

ответ

0

Ответ ниже может помочь вам. SQL выглядит длинно, но логика проста, просто группировка D и N и, наконец, соединение. Возможно, вы можете работать от этого.

DECLARE @Lu_Dt table 
(id int identity(1,1),Dt Date) 
INSERT INTO @Lu_Dt VALUES('2014-05-01'), 
('2014-05-02'),('2014-05-03'), 
('2014-05-04'),('2014-05-05') 

DECLARE @tab table 
(EID int,PID varchar(15),In_Time datetime,Out_Time datetime,[Shift] Char(1)) 
INSERT INTO @tab Values 
(100,'S001','2014-05-01 07:10','2014-05-01 19:20','D'), 
(100,'S001','2014-05-04 07:00','2014-05-04 19:00','D'), 
(100,'S001','2014-05-04 19:00','2014-05-05 07:00','N') 

SELECT * FROM @tab 

enter image description here

DECLARE @refTab table 
(id int identity(1,1),EID int, Dt Date,[shift] varchar(3)) 

INSERT INTO @refTab 

SELECT  Lu.EID,Lu.Dt,coalesce(LU1.[Flag],LU2.[Flag]) [shift] 
FROM  (SELECT *,100 EID FROM @Lu_Dt) Lu 
LEFT JOIN (SELECT D.EID,D.In_Time,'D/N' [Flag] 
      FROM (SELECT EID,CAST(In_Time AS DATE) In_Time FROM @tab Where Shift = 'D') D 
      JOIN (SELECT EID,CAST(In_Time AS DATE) In_Time FROM @tab Where Shift = 'N') N 
      ON  D.In_Time = N.In_Time AND D.EID = N.EID) LU1 ON Lu.Dt = LU1.In_Time 
LEFT JOIN (SELECT CAST(In_Time AS DATE) In_Time,'D' [Flag] FROM @tab Where Shift = 'D') LU2 ON Lu.Dt = LU2.In_Time 
LEFT JOIN (SELECT CAST(In_Time AS DATE) In_Time,'N' [Flag] FROM @tab Where Shift = 'N') LU3 ON Lu.Dt = LU3.In_Time 

SELECT * FROM @refTab 

enter image description here

SELECT * 
FROM (SELECT EID,Dt,[shift] from @refTab) As src 
PIVOT 
(MAX([shift]) for Dt in 
    ( [2014-05-01], 
     [2014-05-02], 
     [2014-05-03], 
     [2014-05-04], 
     [2014-05-05])) AS PivotTable; 

Результат

enter image description here

Поскольку существует много жесткого кодирования, его нельзя использовать как таковое. Надеюсь, это помогло.

+0

Большое спасибо. Это помогло. Если вы не возражаете, не могли бы вы объяснить вторую часть вашего кода (начало с 'INSERT INTO @ refTab' ...) будет очень полезно. – Deva

+1

Я сохранил результат в таблице temp @refTab, так что запись инструкции PIVOT будет выглядеть менее сложной. –

Смежные вопросы