2012-04-24 46 views
2

我已經追捕了兩天尋找我不需要的東西。我相信這很簡單,但這不是我的包。事件錶行到列使用CTE?

表中我存儲了一個EmployeeID和TimeStamp。我需要選擇每隔一行,使得奇數行和偶數行映射到新列像這樣:

輸入表TimePunches:

 
EmployeeID  Time 
1    08:00:00 
1    12:00:00 
1    12:30:00 
1    17:00:00 

輸出繼電器表:

 
Employee  TimeIn  TimeOut 
1    08:00:00  12:00:00 
1    12:30:00  17:00:00 

我會計算出每個輸出行的計算時間,然後找出如何將行轉換爲兩列。我知道這將輸出的垃圾,如果它不返回偶數行,但我想走到這一步第一;)

回答

0
with prepared_data as (
    select 
    EmployeeID, 
    Time, 
    row_number() over(partition by EmployeeID order by Time) as num 
    from TimePunches 
) 
select 
    p1.EmployeeID, 
    p1.Time as TimeIn, 
    p2.Time as TimeOut 
from 
    prepared_data p1 
    left join prepared_data p2 on p1.EmployeeID = p2.EmployeeID and p1.num + 1 = p2.num 
where 
    p1.num % 2 = 1 
order by 
    p1.EmployeeID, 
    p1.num 
+0

編輯完成後,它就像一個魅力。我不知道該怎麼感謝你才足夠。哦,等等...我在哪裏發送支票? :) – user1354197 2012-04-24 22:09:33

0

一種解決方案是,在僞代碼:

declare @timeIn datetime, @timeOut datetime 
declare @emp int 

get one row at a time { 

if (row is even) 
    @timeIn = Time from row 
} 
else { 
    @timeOut = Time from row 
    @emp = Employee from row 
    insert into #tempTable @emp, @timeIn, @timeOut 
} 

select #tempTable 

要一次獲得一行,可以使用ROW_NUMBER或遊標。

0

爲了記錄,這個表結構需要改變,但它可以做你想做的。這個查詢讓我覺得各種各樣的骯髒,我永遠不會考慮在我的代碼中使用它,但它會工作,所以認爲你自己警告。

with rank1 as (
SELECT EmployeeID, Time, RANK() OVER (PARTITION BY EmployeeID ORDER BY Time) as rank 
FROM TimePunches), 
rank2 as (
SELECT EmployeeID, Time, RANK() OVER (PARTITION BY EmployeeID ORDER BY Time) as rank 
FROM TimePunches) 

SELECT rank1.EmployeeID, rank1.Time as timeIn, rank2.Time as timeOut 
FROM rank1 
JOIN rank2 on rank1.EmployeeID = rank2.EmployeeID AND rank1.rank % 2 = 1 AND rank1.rank - (rank1.rank % 2) = rank2.rank 
1

另一種解決方案涉及ROW_NUMBER()和,換一換,PIVOT

WITH prepared AS (
    SELECT 
    EmployeeID, 
    Time, 
    TimeRow = (ROW_NUMBER() OVER (PARTITION BY EmployeeID ORDER BY Time) - 1)/2 
    TimeKind = 
     CASE (ROW_NUMBER() OVER (PARTITION BY EmployeeID ORDER BY Time) - 1) % 2 
     WHEN 0 THEN 'TimeIn' 
     WHEN 1 THEN 'TimeOut' 
     END 
    FROM TimePunches 
) 
SELECT 
    EmployeeID, 
    TimeIn, 
    TimeOut 
FROM prepared 
PIVOT (
    MAX(Time) FOR TimeKind IN (TimeIn, TimeOut) 
) p 
ORDER BY 
    EmployeeID, 
    TimeRow 

您可以使用此查詢on SQL Fiddle玩。