2

我已经狩猎了两天寻找我需要的东西无济于事。我相信这也很简单,但这不是我的包。

我的表存储了一个 EmployeeID 和时间戳。我需要选择每隔一行,以便奇数行和偶数行映射到新列,如下所示:

输入表 TimePunches:

员工ID时间
1 08:00:00
1 12:00:00
1 12:30:00
1 17:00:00

输出表:

员工 TimeIn TimeOut
1 08:00:00 12:00:00
1 12:30:00 17:00:00

在弄清楚如何将行转换为恰好两列之后,我将从每个输出行计算时间。我意识到如果它不返回偶数行,这会输出垃圾,但我想先做到这一点;)

4

4 回答 4

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

您可以在 SQL Fiddle 上使用此查询。

于 2012-04-24T18:30:48.743 回答
0

One solution might be, in pseudo-code:

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

To get a row at a time you can use ROW_NUMBER or cursors.

于 2012-04-24T16:31:36.083 回答
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
于 2012-04-24T16:43:00.953 回答
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
于 2012-04-24T16:22:45.440 回答