【问题标题】:Sql Pivot on timeSql Pivot 准时
【发布时间】:2018-10-28 06:04:14
【问题描述】:

表 1:每日出勤数据:

    att_date    emp_code    emp_name    in_time                out_time
    2018-10-21  9999         Test   2018-10-21 08:00:00.000   2018-10-22 06:00:00.000

表 2:Trnevents

emp_readr_id    DT              EVENTID
    9999    2018-10-24 07:00:00.000 0
    9999    2018-10-24 05:00:00.000 0
    9999    2018-10-24 03:00:00.000 0
    9999    2018-10-23 21:00:00.000 0
    9999    2018-10-23 19:00:00.000 0
    9999    2018-10-23 06:00:00.000 0
    9999    2018-10-22 06:00:00.000 0
    9999    2018-10-21 08:00:00.000 0

我使用此查询来获取时间和时间之间的所有时间,下面的查询工作正常,但我尝试使用数据透视表在行中生成。使用转出时间显示在下一行。

declare @tempProcesstable as table(
    [id] [nvarchar](200) NULL,
    [time_stamp] datetime NULL,
    [AccessType] varchar(3)  NULL) 
insert into @tempProcesstable 

        select distinct t1.emp_Reader_id, t1.DT,t1.eventid from   daily_attendance_data t2 join trnevents t1
on t1.emp_reader_id=t2.emp_reader_id where   (CONVERT(VARCHAR(26), t2.att_Date, 23) >=CONVERT(VARCHAR(26), '2018-10-20', 23) 
                       and CONVERT(VARCHAR(26), t2.att_date, 23) <=CONVERT(VARCHAR(26), '2018-10-21', 23))
                   and
                   (t1.DT >=t2.in_time 
                       and  t1.DT <=t2.out_time)
                        --   and t1.emp_reader_id=1000
                               group by t1.emp_Reader_id,t1.dt,t1.eventid order by t1.emp_reader_id,DT asc
                  ; With CheckIns
As (Select Rowemp_reader_id = Row_Number() Over (Partition by id, Cast(time_stamp As Date) Order By time_stamp),
        id, time_stamp,
        [Date] = Cast(time_stamp As Date),

        [Time] = Cast(time_stamp As Time(0))
    From @tempProcesstable)
Select Pvt.id,B.emp_name ,  [Date], CHECK1, CHECK2,Cast(dateadd(ss,datediff(ss,CHECK1,CHECK2),0) As Time(0)) Total1,
 CHECK3, CHECK4,Cast(dateadd(ss,datediff(ss,CHECK3,CHECK4),0) As Time(0)) Total2
From (Select id, [Date], [Time],
        CHECKNum = 'CHECK' + Cast(Rowemp_reader_id As varchar(11))
    From CheckIns) As P
Pivot (Min([Time])
    For CheckNum In (Check1, [Check2], Check3, Check4)
    ) As Pvt    

     LEFT OUTER JOIN
                      dbo.employee AS B ON Pvt.id= B.emp_reader_id

我的输出:

id  emp_name    Date    CHECK1  CHECK2  Total1  CHECK3  CHECK4  Total2  
1048    Singh   2018-10-21  07:06:07    17:34:05    10:27:58    NULL    NULL    NULL    
9999    Test    2018-10-21  08:00:00    NULL    NULL    NULL    NULL    NULL    NULL
9999    Test    2018-10-22  06:00:00    NULL    NULL    NULL    NULL    NULL    NULL

预期输出:

我也想要从晚上到早上的时间和时间之间的所有时间。 谁能帮我纠正这个问题。

id  emp_name    Date    CHECK1  CHECK2  Total1  CHECK3  CHECK4  Total2  
1048    Singh   2018-10-21  07:06:07    17:34:05    10:27:58    NULL    NULL    NULL    
9999    Test    2018-10-21  08:00:00    06:00:00    NULL    NULL    NULL    NULL    NULL

【问题讨论】:

  • 您的查询太复杂了。您能否提供一些示例数据并期望示例的结果让您的问题更简单:)
  • 如果某些员工有夜班,一切都可以正常工作,例如看到我的输出 9999 在 8:00 有 intime,在 06:00 有 outtime,对于这种情况,我想要单行作为上述员工。同一日期没有 pblm 但下一个日期不合适
  • 我写了一个答案你可以试试,@考勤系统
  • 谢谢,但不是我的预期输出

标签: sql sql-server-2008 pivot pivot-table


【解决方案1】:

您可以尝试使用ROW_NUMBER()窗口函数按每个日期制作行号。

然后使用条件聚合函数做pivot

SELECT emp_readr_id,
       emp_name,
       [Date],
       MAX(CASE WHEN RN = 1 THEN time END) CHECK1,
       MAX(CASE WHEN RN = 2 THEN time END) CHECK2,
       MAX(CASE WHEN RN = 3 THEN time END) CHECK3,
       MAX(CASE WHEN RN = 4 THEN time END) CHECK4
FROM (
SELECT emp_readr_id,
       emp_name,
       CONVERT(VARCHAR(10),DT,120) 'Date',
       ROW_NUMBER() OVER(PARTITION BY CONVERT(VARCHAR(10),DT,120) ORDER BY DT) rn,
        CONVERT(VARCHAR(10),DT,108) time
FROM Daily d 
JOIN Trnevents t on t.DT between d.in_time and d.out_time
) t1
group by emp_readr_id,
       emp_name,
       [Date]

sqlifddle

【讨论】:

  • 我的预期输出超时 nxt 天意味着它将仅在同一日期显示第二天的时间
猜你喜欢
  • 1970-01-01
  • 2012-06-17
  • 2016-01-29
  • 2012-01-13
  • 2018-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多