SELECT
    员工编号,上班日期,MAX(上午签到时间) AS 上午签到时间,
    MAX(上午签退时间) AS 上午签退时间,
    ...
   ...
FROM tb
GROUP BY 员工编号,上班日期

解决方案 »

  1.   

    select  PERSONNO AS "员工编号",max(DATETIME) AS "上班日期",max(MITIME) AS "上午签到时间",max(MOTIME) AS "上午签退时间",max(AITIME) AS "下午签到时间",max(AOTIME) AS "下午签退时间" from ATTENDANCE group by 员工编号 
      

  2.   

    --modify
    select  PERSONNO AS "员工编号",max(DATETIME) AS "上班日期",max(MITIME) AS "上午签到时间",max(MOTIME) AS "上午签退时间",max(AITIME) AS "下午签到时间",max(AOTIME) AS "下午签退时间" from ATTENDANCE group by PERSONNO  order by PERSONNO 按照PERSONNO  分组,取最大的值。
      

  3.   

    建议用存储过程+临时表
    如果同一天上班误操作刷了两次卡数据会怎么样? 用max 还是用 min ? 应该还要判断时间点正确性
    一般考勤建议上下班时间点左右10分钟内为有效数据。
      

  4.   

    不需要重新建表。
    楼主是要将上面数据表的内容,编程下面那个数据表的内容,因此,select语句是不可能完成这个任务的。而且我估计楼主只是将部分数据列了出来。我的建议是,针对每个员工每天的上下班时间分别做处理:
    1001          2009-04-02          08:00:01          NULL        12:00:11          NULL 
    1001          2009-04-02          NULL              11:00:00        NULL        17:00:24 
    将这两条中的其中条的NULL用另外一条记录对应的字段中的值替换,然后删除仍然NULL的那条记录:
    1001          2009-04-02          08:00:01          11:00:00    12:00:11        17:00:24  
    1001          2009-04-02          NULL              11:00:00        NULL        17:00:24 (删除)
    那么最后就剩下:
    1001          2009-04-02          08:00:01          11:00:00    12:00:11        17:00:24
    对整个数据表做类似处理。整个处理过程可以写成一个存储过程。以上就是清理楼主提及的那个数据表比较通常用到的、也是很有效的方法。当然如果可能,最好数据库不要连网运行,待清理完毕后再连网运行(连网运行也没有太大的关系,只是在清理数据表的过程中,用户可能会觉得比平时要稍慢一些)。