Delphi 如何避免加入MS-ACCESS(房间访问管理)中的重复

Delphi 如何避免加入MS-ACCESS(房间访问管理)中的重复,delphi,ms-access,Delphi,Ms Access,这是用于房间访问管理,我已从外部设备导出csv文件这是原始数据: 2019.05.31 20:20:28 p+ 462 SALES MGR, ROVING GUARD 2019.05.31 20:23:35 p- 462 SALES MGR, ROVING GUARD 2019.05.31 20:24:05 p+ 461 SALES MGR, ROVING GUARD 2019.05.31 20:24:13 p- 461 SALES MGR, ROVING

这是用于房间访问管理,我已从外部设备导出csv文件这是原始数据:

2019.05.31  20:20:28    p+  462 SALES MGR, ROVING GUARD
2019.05.31  20:23:35    p-  462 SALES MGR, ROVING GUARD
2019.05.31  20:24:05    p+  461 SALES MGR, ROVING GUARD
2019.05.31  20:24:13    p-  461 SALES MGR, ROVING GUARD
2019.05.31  20:24:40    p+  460 SALES MGR, ROVING GUARD
2019.05.31  20:24:51    p-  460 SALES MGR, ROVING GUARD
2019.05.31  20:25:31    p+  447 SALES MGR, ROVING GUARD
2019.05.31  20:25:36    p-  447 SALES MGR, ROVING GUARD
2019.05.31  20:26:14    p+  459 SALES MGR, ROVING GUARD
2019.05.31  20:26:42    p+  458 SALES MGR, ROVING GUARD
2019.05.31  20:26:46    p-  458 SALES MGR, ROVING GUARD
2019.05.31  20:27:49    p+  443 SALES MGR, ROVING GUARD
2019.05.31  20:28:01    p-  443 SALES MGR, ROVING GUARD
2019.05.31  20:28:16    p+  443 SALES MGR, ROVING GUARD
2019.05.31  20:28:21    p-  443 SALES MGR, ROVING GUARD
2019.05.31  20:29:05    p+  445 SALES MGR, ROVING GUARD
2019.05.31  20:29:09    p-  445 SALES MGR, ROVING GUARD
注:p+表示进入房间,p-表示退出房间

下载后,我会将csv文件导入到我的应用程序中,然后将p+和p-分开,最后将其记录到数据库中。这是数据库结构:

如我们所见,与原始数据相比,重复且不正确的记录,请帮助我解决此问题或建议其他方法。谢谢

顺便说一句,这是我用来获取结果的查询:

SELECT tblActivityPP.DateLog AS DateIN,
tblActivityPN.DateLog AS DateOUT, 
tblActivityPP.TimeLog AS TimeIN, 
tblActivityPN.TimeLog AS TimeOUT, 
tblActivityPP.Room,  
tblActivityPN.Room AS RoomOut, 
tblActivityPP.Position, 
tblActivityPP.Account, 
tblActivityPN.ID, 
tblActivityPP.ID
FROM tblActivityPP 
LEFT JOIN 
tblActivityPN ON 
(tblActivityPP.Position = tblActivityPN.Position) 
AND 
(tblActivityPP.Room = tblActivityPN.Room) 
AND 
(tblActivityPP.[Account] = tblActivityPN.[Account])

为了得到不同的结果,需要使用distinct子句

SELECT DISTINCT 
tblActivityPP.DateLog AS DateIN,
tblActivityPN.DateLog AS DateOUT, 
tblActivityPP.TimeLog AS TimeIN, 
tblActivityPN.TimeLog AS TimeOUT, 
tblActivityPP.Room,  
tblActivityPN.Room AS RoomOut, 
tblActivityPP.Position, 
tblActivityPP.Account, 
tblActivityPN.ID, 
tblActivityPP.ID
FROM tblActivityPP 
LEFT JOIN 
tblActivityPN ON 
(tblActivityPP.Position = tblActivityPN.Position) 
AND 
(tblActivityPP.Room = tblActivityPN.Room) 
AND 
(tblActivityPP.[Account] = tblActivityPN.[Account])

数据是正确的,但443房间被输入/离开了三次

| 2019.05.31 | 20:27:49 | p+ | 443 | SALES MGR | ROVING GUARD |
| 2019.05.31 | 20:28:01 | p- | 443 | SALES MGR | ROVING GUARD |
| 2019.05.31 | 20:28:16 | p+ | 443 | SALES MGR | ROVING GUARD |
| 2019.05.31 | 20:28:21 | p- | 443 | SALES MGR | ROVING GUARD |
...
| 2019.05.31 | 20:30    | p+ | 443 | SALES MGR | ROVING GUARD |  (this data is from image P+)
| 2019.05.31 | 20:30    | p- | 443 | SALES MGR | ROVING GUARD |  (this data is from image P-)
如果您在房间中加入tblActivityPP和tblActivityPN,则443房间的tblActivityPP中会有93行*tblActivityPN中会有3行。正确结果tblActivityPP中的每一行都连接到tblActivityPN中的每一行,但不是您想要的

你们想知道进入后房间什么时候离开。这是输入后的第一次休假,将数据限制为一行

不要创建两个表具有相同字段名的表通常应该是一个具有附加字段的表,其中存储了表名所描述的属性,只需将原始数据导入一个表,例如,ÀActivityLog,但日期和时间datetime只有一个字段,创建一个TableAccount并将PKPrimaryKey作为FKForeignKey存储在表中,Skippositions应存储在CountTable中,并为进入/离开的房间创建TableActivity,并将PK存储为FK,而不是P+/P-`

例如表Àactivitylog:

| Timestamp           | ActivityID | Room | AccountID |
|---------------------|:----------:|:----:|:---------:|
| 2019.05.31 20:20:28 |      1     |  462 |     1     |
| 2019.05.31 20:23:35 |      2     |  462 |     1     |
| 2019.05.31 20:24:05 |      1     |  461 |     1     |
| 2019.05.31 20:24:13 |      2     |  461 |     1     |
| 2019.05.31 20:24:40 |      1     |  460 |     1     |
| 2019.05.31 20:24:51 |      2     |  460 |     1     |
| 2019.05.31 20:25:31 |      1     |  447 |     1     |
| 2019.05.31 20:25:36 |      2     |  447 |     1     |
| 2019.05.31 20:26:14 |      1     |  459 |     1     |
| 2019.05.31 20:26:42 |      1     |  458 |     1     |
| 2019.05.31 20:26:46 |      2     |  458 |     1     |
| 2019.05.31 20:27:49 |      1     |  443 |     1     |
| 2019.05.31 20:28:01 |      2     |  443 |     1     |
| 2019.05.31 20:28:16 |      1     |  443 |     1     |
| 2019.05.31 20:28:21 |      2     |  443 |     1     |
| 2019.05.31 20:29:05 |      1     |  445 |     1     |
| 2019.05.31 20:29:09 |      2     |  445 |     1     |
所有字段都应编入索引

活动:

表格账户:

所有ID字段都是PrimaryKey和Autoincrement

然后通过FilteringActivityLorgForActivityId创建两个查询作为BlactivityPP/TBlactivityPNB的替换

QRY互动:

选择ActivityLog.ID ,FormatActivityLog.Timestamp,mm/dd/yyyy作为日期日志 ,FormatActivityLog.Timestamp,HH:nn作为TimeLog ,Activites.ActivityName ,ActivityLog.Room ,Positions.PositionName作为Position ,Accounts.AccountName作为帐户 从活动日志 ActivityLog.ActivityID=Activities.ID上的内部联接活动 ActivityLog.AccountID=Accounts.ID上的内部联接帐户 Accounts.PositionID=Positions.ID上的内部联接位置 其中ActivityLog.ActivityID=1; 活动:

选择ActivityLog.ID ,FormatActivityLog.Timestamp,mm/dd/yyyy作为日期日志 ,FormatActivityLog.Timestamp,HH:nn作为TimeLog ,Activites.ActivityName ,ActivityLog.Room ,Positions.PositionName作为Position ,Accounts.AccountName作为帐户 从活动日志 ActivityLog.ActivityID=Activities.ID上的内部联接活动 ActivityLog.AccountID=Accounts.ID上的内部联接帐户 Accounts.PositionID=Positions.ID上的内部联接位置 其中ActivityLog.ActivityID=2; 您的查询结果:

选择ActivityLog.ID ,FormatActivityLog.Timestamp,mm/dd/yyyy作为日期输入 ,FormatActivityLog.Timestamp,HH:nn作为TimeIn, ,从ActivityLog中选择MinTimestamp作为ALog,其中ALog.AccountID=ActivityLog.AccountID,ALog.Timestamp>ActivityLog.Timestamp,ALog.ActivityID=2作为Timestamp ,FormatTimestampOut,mm/dd/yyyy作为日期输出 ,FormatTimestampOut,HH:nn作为超时 ,Activites.ActivityName ,ActivityLog.Room ,Positions.PositionName作为Position ,Accounts.AccountName作为帐户 从活动日志 ActivityLog.ActivityID=Activities.ID上的内部联接活动 ActivityLog.AccountID=Accounts.ID上的内部联接帐户 Accounts.PositionID=Positions.ID上的内部联接位置 其中ActivityLog.ActivityID=1; 这将获取所有房间输入的事件,并为该帐户再选择下一个房间左侧事件


所有SQL代码未经测试,缺少括号、别名等,但应显示一般方法。

请显示数据p+表格、p-表格,并以表格格式显示结果,如原始数据而非图像!
| ID | ActivityName | ActivityDescription |
|----|:------------:|---------------------|
| 1  |      P+      | Room entered        |
| 2  |      P-      | Room left           |
| ID | AccountName  | PositionID                                       |
|----|--------------|--------------------------------------------------|
| 1  | ROVING GUARD | 3 (FK for Position SALES MGR in table Positions) |