所以我一直在四处寻找并没有找到太多东西。我提前道歉,因为这可能是错误的做法,但事实就是如此。
所以我必须跟踪同事完成的课程。这是通过提供MS访问数据库的Excel工作表完成的。有3个字段供应给我。
全名,课程名称和完成日期。
我知道我这里没有主键,因此我尝试创建一个只会附加从Excel工作表中提取的唯一记录的查询。我可以基于单个字段执行此操作但需要帮助使我的查询仅在全名和课程名称不相同时附加它,例如
Joe Somebody, Course#1, 14feb13
Joe Somebody, Course#2, 15feb13
Joe Somebody, Course#1, 15feb13
我需要一个查询,它会将前两行附加到表中但忽略第三行,因为该人已经完成了课程#1。这就是我到目前为止基本上将我的名字字段转换为主键。
INSERT INTO table [Full name], [Course], [Date]
SELECT excel_table.[Full name], excel_table.[Course], excel_table.[Date]
FROM excel_table
WHERE excel_table.[Full name] Not in (SELECT table.[Full Name] FROM table)
我最后也有一些不是空的东西,但我不认为它会与这个问题相关。
答案 0 :(得分:2)
执行此操作的最简单方法是不添加重复项是添加索引。在这种情况下,复合主键似乎就是答案。只需选择要包含在复合键中的所有字段,然后单击“主键”按钮:
在包含主键的任何字段中不允许使用空值,但只要字段组合不匹配,就可以重复每个字段中的数据。所以:
Joe Somebody, Course#1, 14feb13 <-- good
Joe Somebody, Course#2, 15feb13 <-- good
Joe Somebody, Course#1, 15feb13 <-- fails
Joe SomebodyElse, Course#1, 14feb13 <-- good
现在,如果使用查询设计窗口运行普通追加查询构建,如果记录在Excel导入表中存在两次或已存在于Access中,则会出现错误:
答案 1 :(得分:0)
您实际上并不需要复合主键。事实上,Access中有一些地方鼓励您不使用复合主键。您可以使用简单的整数主键创建Access表:
create table CourseCompletions (
ID autoincrement primary key
, FullName varchar(100)
, CourseName varchar(100)
, CompletionDate date
);
然后你可以吞下Excel文件中的所有数据:
insert into CourseCompletions (
, FullName
, CourseName
, CompletionDate
) select
[Full name]
, [Course]
, [Date]
from excel_table;
这将为输入Excel表的每一行提供一个唯一编号,并将其存放在Access表中。现在,您需要决定如何从CourseCompletions表中拒绝冲突的行。 (以下查询仅显示您决定不拒绝的记录。)如果您想在以后拒绝同一课程的同一人的完成:
select
ID
, FullName
, CourseName
, min(CompletionDate)
from CourseCompletions
group by
ID
, FullName
, CourseName;
如果您想在较早的日期拒绝完成,只需将MIN更改为MAX。
如果您要拒绝Excel表格中较早出现的任何课程:
select
cc1.ID
, cc1.FullName
, cc1.CourseName
, cc1.CompletionDate
from CourseCompletions as cc1
inner join (
select
max(ID) as WantedID
, FullName
, CourseName
from CourseCompletions
group by FullName, CourseName
) as cc2
on cc1.ID = cc2.WantedID;
要拒绝稍后在Excel表格中出现的课程完成情况,只需将MAX替换为MIN。
因此,使用整数主键可以为您提供一些选项。