有如下刷卡数据
  技术管理中心    李建生   2006-01-01     07:55
  技术管理中心    李建生   2006-01-01     14:15
  技术管理中心    李建生   2006-01-01     16:22
  技术管理中心    李建生   2006-01-02     08:15
  技术管理中心    李建生   2006-01-02     09:15
  技术管理中心    李建生   2006-01-02     11:15
  技术管理中心    李建生   2006-01-03     07:22
  技术管理中心    李建生   2006-01-03     08:15
  .
  .
  .
  技术管理中心    袁虎     2006-01-01     07:55
  技术管理中心    袁虎     2006-01-01     10:55
  技术管理中心    袁虎     2006-01-02     07:55
  .........
  技术管理中心    王二     2006-01-01     10:55
  技术管理中心    王二     2006-01-01     07:43
  技术管理中心    王二     2006-01-02     07:43
  .........  以上数据是查询到的2006年1月技术管理中心的刷卡记录(一个人一天有多条刷卡记录)
  现在客户选择要查询2006年1月技术管理中心的人员考勤,在8:00之前刷卡的就算
  正常上班,8点以后的算迟到,如果某月某天没有刷卡记录,则记录旷工,并且显示旷工的日期
  周六、日不记考勤。显示如下:
    部门名称        人员姓名     正常出勤   迟到    旷工
  技术管理中心       李建生         21        2      0
  技术管理中心       袁虎           17        5      1
  技术管理中心       王二           20        2      1
(如果有旷工记录,则双击显示具体哪些天旷工)
    这怎么实现啊!!我没办法了!!望各位大虾们指点指点
  
  分不够了!!不好意思!!不行我开马甲给分
  

解决方案 »

  1.   

    select a.部门名称, a.人员名称, b.正常出勤, c.迟到, d.旷工 from 
    (select 部门名称, 人员名称 from table1 group by 部门名称,人员名称) a
    left join (select 部门名称, 人员名称, count(*) as 正常出勤 from (select * from table1 where DatePart(Hh, 刷卡时间)<=8 ) btemp group by btemp.部门名称,btemp.人员名称) b ON a.人员名称 = b.人员名称
    left join (select 部门名称, 人员名称, count(*) as 迟到 from (select * from table1 where DatePart(Hh, 刷卡时间>8) ctemp group by ctemp.部门名称, ctemp.人员名称) c 
    ON a.人员名称 = c.人员名称
    left join (select 部门名称, 人员名称, count(*) as 旷工 from 正常上班时间表 where not exists(select * from table1)) d ON a.人员名称 = d.人员名称
      

  2.   

    一天某个人有多条刷卡记录,怎么在找到这个人的第一条记录后,跳过这一天其他的刷卡记录
    往下找第二天的第一条记录!!看ourlin(游荡于代码间的孤魂) 这位大哥的东西有点昏!!正在研究
      

  3.   

    还有  ourlin(游荡于代码间的孤魂) 好象没区分星期六、日啊
      

  4.   

    那就改一下:
    select a.部门名称, a.人员名称, b.正常出勤, c.迟到, d.旷工 from 
    (select 部门名称, 人员名称 from table1 group by 部门名称,人员名称) a
    left join (select 部门名称, 人员名称, count(*) as 正常出勤 from (select 人员名称,Convert(char(10), 刷卡时间,120) as 日期, min(Convert(char(11), 刷卡时间,114)as 时间 from table1 group by 人员名称,Convert(char(10), 刷卡时间, 120)) time1 where (time1.时间<=8) (datePart(week,time2.日期)between 1 and 5) group by time1.人员名称) b
     ON a.人员名称 = b.人员名称
    left join (select 部门名称, 人员名称, count(*) as 迟到 from (select 人员名称,Convert(char(10), 刷卡时间,120) as 日期, min(Convert(char(11), 刷卡时间,114)as 时间 from table1 group by 人员名称,Convert(char(10), 刷卡时间, 120)) time2 where (time2.时间>8 ) and (datePart(week,time2.日期)between 1 and 5) group by time1.人员名称) c 
    ON a.人员名称 = c.人员名称
    left join (select 部门名称, 人员名称, count(*) as 旷工 from 正常上班时间表 where not exists(select * from table1)) d ON a.人员名称 = d.人员名称
      

  5.   

    能麻烦解释一下你写的东西吗??(90度鞠躬第一次)还有最后一个问题!!
    如果8点前刷了2次卡的话怎么办??
    问完去调SQL语句!!(90度鞠躬第二次)(估计这个SQL得调个半天).....自嘲中。。
      

  6.   

    "能麻烦解释一下你写的东西吗??(90度鞠躬第一次)" 不用客气^_^,我给出的是一种思路:select a.部门名称, a.人员名称, b.正常出勤, c.迟到, d.旷工 from 
    --我觉得除了刷卡数据表table1外,应该还有一个员工表table0:
    (select 部门名称, 人员名称 from table0) a
    --联接正常出勤的查询,关键在找到最早一次刷卡的查询,注意日期时间星期的转换:
    left join (select 部门名称, 人员名称, count(*) as 正常出勤 from (select 人员名称,Convert(char(10), 刷卡时间,120) as 日期, min(Convert(char(11), 刷卡时间,114)as 时间 from table1 group by 人员名称,Convert(char(10), 刷卡时间, 120)) time1 where (time1.时间<=8) and (datePart(week,time2.日期)between 1 and 5) group by time1.人员名称) b
     ON a.人员名称 = b.人员名称--联接迟到人员的查询:
    left join (select 部门名称, 人员名称, count(*) as 迟到 from (select 人员名称,Convert(char(10), 刷卡时间,120) as 日期, min(Convert(char(11), 刷卡时间,114)as 时间 from table1 group by 人员名称,Convert(char(10), 刷卡时间, 120)) time2 where (time2.时间>8 ) and (datePart(week,time2.日期)between 1 and 5) group by time1.人员名称) c 
    ON a.人员名称 = c.人员名称--此处有改动!必须还有一个正常上班日期表table2(可以事先建立), 以便找出旷工日期:
    left join (select 部门名称, 人员名称, 旷工=(select count(*) from table2 where table2.日期 not in (select 日期 from table1 where 人员名称=d.人员名称)) from table0 d ON a.人员名称 = d.人员名称