MS Access Query获取每个ID的进入时间和退出时间

时间:2017-10-22 13:12:56

标签: sql ms-access

我需要帮助才能使用考勤表,在我的公司,我们有一个单一的读卡器,可以进出设施。

我能够从软件中提取我后来导入访问的excel表,列标题(字段)位于临时表中,如下所示。

问题是工作人员进去&在一天中,我需要将每个CardID的第一个和最后一个入场时间添加到另一个表格中。

*AttendanceDate* - *AttendanceTime* - *CardID*
10/09/2017 - 08:00:00 - 123  
10/09/2017 - 09:20:00 - 123  
10/09/2017 - 10:00:00 - 123  
10/09/2017 - 15:00:00 - 123  
10/09/2017 - 09:00:00 - 675  
10/09/2017 - 12:00:00 - 675  
11/09/2017 - 09:00:00 - 675  
11/09/2017 - 16:00:00 - 675  

我需要创建一个查询,它会为每个cardID获取每天的第一个和最后一个时间记录,并将其附加到另一个工作表以获得这样的结果。

*AttendanceDate* - *EntryTime* - *ExitTime* - *CardID*
10/09/2017 - 08:00:00 - 15:00:00 - 123  
10/09/2017 - 09:00:00 - 12:00:00 - 675  
11/09/2017 - 09:00:00 - 16:00:00 - 675  

这甚至可能吗?

3 个答案:

答案 0 :(得分:1)

这是一个聚合查询:

select AttendanceDate, min(AttendanceTime) as entrytime,
       max(AttendanceTime) as exittime, CardId
from t
group by AttendanceDate, CardId;

要将其添加到另一个表,您可以使用select into(创建表)或insert(如果已创建表)。

插入内容如下所示:

insert into t2(AttendanceDate, entrytime, exittime, CardId)
    select AttendanceDate, min(AttendanceTime) as entrytime,
           max(AttendanceTime) as exittime, CardId
    from t
    group by AttendanceDate, CardId;

我不相信MS Access支持“upsert”,这将是一个单独的操作。因此,在两列上创建唯一索引:

create unique index unq_t_AttendanceDate_CardId on t(AttendanceDate, CardId);

然后尝试插入。如果失败,则进行更新。这是关于该主题的question

答案 1 :(得分:1)

考虑背靠背运行两个操作查询:

  1. 使用聚合和NOT IN / NOT EXISTS / LEFT JOIN...NULL子句附加查询(通过SQL Server链接仍然在MS Access中兼容),其中仅附加新的 CardIDs AttendanceDate 对。
  2. 使用域聚合DMinDMax更新查询(因为聚合查询联接不是可更新的查询),其中现有 CardIDs AttendanceDate 对已更新。
  3. 追加查询 (仅使用NOT EXISTS附加新的CardID和AttendanceDate配对)

    INSERT INTO otherTable (CardID, AttendanceDate, EntryTime, ExitTime)
    SELECT t.CardId, t.AttendanceDate, MIN(t.AttendanceTime), MAX(t.AttendanceTime)
    FROM originTable t
    WHERE NOT EXISTS
       (SELECT 1 FROM otherTable sub
        WHERE sub.CardID = t.CardID AND sub.AttendanceDate = t.AttendanceDate)
    GROUP BY t.CardID, t.AttendanceDate;
    

    更新查询 (仅使用域聚合更新现有CardID和AttendanceDate配对)

    UPDATE otherTable t1 INNER JOIN originTable t2 
        ON t1.CardID = t2.CardID AND t1.AttendanceDate = t2.AttendanceDate
    SET t1.entrytime = DMin("AttendanceTime", "originTable", "CardID=" & t1.CardID & 
                            " AND AttendanceDate=#" & t1.AttendanceDate & "#"),
        t1.exittime = DMax("AttendanceTime", "originTable", "CardID=" & t1.CardID & 
                           " AND AttendanceDate=#" & t1.AttendanceDate & "#")
    

答案 2 :(得分:0)

如果表格具有唯一键,则“upsert”肯定是可能的。

来自 Smart Access 的旧提示是我的最爱之一:

  

使用一个查询更新和附加记录

     

作者:Alan Biggs

     

您是否知道可以在Access中使用更新查询进行更新   并同时添加记录?如果你有两个,这很有用   表的版本,tblOld和tblNew,并且您想要集成   从tblNew变为tblOld。

     

请按照以下步骤操作:

     

创建更新查询并添加两个表。加入两个表   将tblNew的关键字段拖到tblOld的匹配字段上。

     
      
  1. 双击关系并选择包含来自tblNew的所有记录的连接选项以及仅包含来自tblNew的记录的连接选项   tblOld。

  2.   
  3. 从tblOld中选择所有字段并将它们拖到QBE网格上。

  4.   
  5. 对于每个字段,在tblNew.FieldName中的“更新到”单元格类型中,其中FieldName与tblOld的字段名称匹配。

  6.   
  7. 从“视图”菜单中选择“查询属性”,并将“唯一记录”更改为“假”。 (这会关闭SQL中的DISTINCTROW选项   视图。如果你留下这个,你将只获得一个空白记录   结果,但您希望添加每个新记录的一个空白记录   to tblOld。)

  8.   
  9. 运行查询,您会看到对tblNew的更改现在位于tblOld中。

  10.         

    这只会添加已添加到tblNew的tblOld记录。   tblOw中不存在于tblNew中的记录仍将保留   tblOld。