如何安排日期/时间进入AM进/出和PM进/出

时间:2012-08-21 09:18:54

标签: sql vb.net ms-access

我正在制作薪资系统,我从zktechnology购买了B3 tft,并希望安排记录。

目前,我可以使用以下格式从生物识别中提取数据:

Count   EmpID   InOutMode   Date
1       1       0           8/20/2012 07:49:01
2       1       1           8/20/2012 12:08:21
3       1       0           8/20/2012 12:43:10
4       1       1           8/20/2012 17:56:15
5       2       0           8/20/2012 07:53:11
6       2       1           8/20/2012 12:02:01
7       2       0           8/20/2012 12:39:56
8       2       1           8/20/2012 17:20:43
9       1       0           8/21/2012 08:10:20
10      1       1           8/21/2012 12:01:26
11      1       0           8/21/2012 13:03:11
12      1       1           8/21/2012 17:11:15
13      2       0           8/21/2012 07:48:26
14      2       1           8/21/2012 12:14:58
15      2       0           8/21/2012 12:59:31
16      2       1           8/21/2012 17:20:12

InOutMode:

0 = In,1 = Out

现在,我想像上面这样转换上面的数据:

EmpID   Date        AM_In       AM_Out      PM_In       PM_Out
1       8/20/2012   07:49:01    12:08:21    12:43:10    17:56:15
2       8/20/2012   07:53:11    12:02:01    12:39:56    17:20:43
1       8/21/2012   08:10:20    12:01:26    13:03:11    17:11:15
2       8/21/2012   07:48:26    12:14:58    12:59:31    17:20:12

所以我可以使用EmpID,Date,AM_In,AM_Out,PM_In,PM_Out字段将其保存到数据库中。

之前我在这里看过类似的代码,但我记不起网址了。

更新

VB.net代码或ms访问格式的SQL是可以接受的。

3 个答案:

答案 0 :(得分:3)

最简单的方法是创建两个交叉表和一个查询,将它们连接到可用的日期和员工。

上午1点交叉表

TRANSFORM Min(tm.Date) AS MinOfDate
SELECT Format([Date],"dd/mm/yyyy") AS dt, tm.EmpID
FROM tm
GROUP BY Format([Date],"dd/mm/yyyy"), tm.EmpID
PIVOT tm.InOutMode;

下午2点交叉表

TRANSFORM Max(tm.Date) AS MinOfDate
SELECT Format([Date],"dd/mm/yyyy") AS dt, tm.EmpID
FROM tm
GROUP BY Format([Date],"dd/mm/yyyy"), tm.EmpID
PIVOT tm.InOutMode;

其中tm是表格的名称。

然后你可以加入这些。

SELECT Alldates.dt, 
       Alldates.empid, 
       am.[0] AS [Am In], 
       am.[1] AS [Am Out], 
       pm.[0] AS [Pm In], 
       pm.[1] AS [Pm Out] 
FROM   ((SELECT DISTINCT Format([date], "dd/mm/yyyy") AS dt, 
                        empid 
        FROM   tm) AS Alldates 
        LEFT JOIN am 
               ON ( Alldates.empid = am.empid ) 
                  AND ( Alldates.dt = am.dt )) 
       LEFT JOIN pm 
              ON ( Alldates.empid = pm.empid ) 
                 AND ( Alldates.dt = pm.dt ); 

答案 1 :(得分:1)

这是一个应该在MS Access中生成所需结果的查询:

select am_in.empid,
    format(am_in.min_in_dt, "MM/DD/YYYY") as [date],
    format(am_in.min_in_dt, "hh:mm:ss") as AM_In,
    format(am_out.min_out_dt, "hh:mm:ss") as AM_Out,
    format(pm_in.max_in_dt, "hh:mm:ss") as PM_In,
    format(pm_out.max_out_dt, "hh:mm:ss") as PM_Out
from
(
    (
        (
           SELECT empid,
              min(dt) as min_in_dt
            FROM yourTable
            where inoutmode = 0
            group by empid
        ) am_in
        inner join
        (
           SELECT empid,
              min(dt) as min_out_dt
            FROM yourTable
            where inoutmode = 1
            group by empid
        ) am_out
            on am_in.empid = am_out.empid
    )
    inner join
    (
       SELECT empid,
          max(dt) as max_in_dt
        FROM yourTable
        where inoutmode = 0
        group by empid
    ) pm_in
        on am_in.empid = pm_in.empid
)
inner join
(
   SELECT empid,
      max(dt) as max_out_dt
    FROM yourTable
    where inoutmode = 1
    group by empid
) pm_out
    on am_in.empid = pm_out.empid

答案 2 :(得分:0)

这样的东西会起作用

select 
    empid,
    dateadd(day,datediff(day,0,DATE),0) as date,
    max(case when sno=1 then convert(varchar(8),DATE,108)) as AM_IN,
    max(case when sno=2 then convert(varchar(8),DATE,108)) as AM_OUT,
    max(case when sno=3 then convert(varchar(8),DATE,108)) as PM_IN,
    max(case when sno=4 then convert(varchar(8),DATE,108)) as PM_OUT
from
(
    select *, 
        row_number() over (partition by empid order by Empid) as sno
    from 
        table 
) as t
group by
    empid,dateadd(day,datediff(day,0,DATE),0)