2

所以我又回来了,遇到了更多的 MS Access 问题。我有一个带有子查询的 INSERT INTO 查询,用于检查数据是否已经存在。

SELECT name, course
FROM foo    
WHERE (name, course) NOT IN (SELECT name, course FROM bar);

解释一下我想要完成的事情,因为上述方法不起作用。

我正在尝试选择表格栏中不存在的复合键。例如,可以将以下内容存储在表格栏中:

"John Doe" , "Calc 101" 
"John Doe" , "English"
"Jane Doe" , "Calc 101"

以下内容可能在表 foo 中:

"John Doe", "Calc 101"
"John Doe", "Science"

查询应返回以下内容:

"John Doe", "Science"

我看过的所有地方都说上面的方法会起作用,我相信它在理论上是有效的。我遇到的问题是 MS Access... 当我尝试运行此查询时,它会弹出说明子查询将返回多个字段。事实上,它应该是我想要它做的就是返回 2 个字段,我可以比较其他 2 个字段。以上 2 个字段是我的“bar”数据库中的复合键。

有关更多背景信息,我正在使用 MS Excel 2007 和 MS Access 2007。Excel 用于输入数据并通过 VB 脚本运行查询。我正在尝试创建一个子查询来检查最终数据库中已经存在的字段,因为我遇到了 MS Access 打开错误并吐出一条关于附加主键的错误消息并在不执行查询的情况下关闭。<-- 由于复合键,这是可以预料的。

4

3 回答 3

1

使用LEFT JOIN并寻找NULL值:

SELECT bar.name, bar.course
FROM bar LEFT JOIN foo ON bar.name = foo.name AND bar.course = foo.course
WHERE foo.name IS NULL

我已经更新了SQLFiddle以包含INSERT后面的 aSELECT以显示最终表格。我还在两个表中添加了复合主键,因此您可以看到您没有得到任何重复的插入。

于 2013-03-08T21:52:05.940 回答
0

您的子查询返回两列。让它返回一个。如果想要一个可以在两列中的 where 子句,请使用 OR

SELECT name, course
FROM foo    
WHERE (name) NOT IN (SELECT name FROM bar) and (course) 
NOT IN (SELECT course FROM bar);

编辑:

您的问题源于规范化问题。建议的重新设计是为学生提供一张桌子,为课程提供一张桌子,并为他们提供一张桌子。例子:

**StudentTable**
studentId(int PK)
firtName(string)
lastName(string)

**ClassTable**
classId(int PK)
ClassName
ClassDesc

**classTable_studentTable**
studentClassID
studentID
classID

每个学生可以有很多班级,每个班级可以有很多学生。这是一个多对多关系,通过使用连接表进行规范化。

现在,如果你想做一个像你问的查询:

Select *.student, *.class
from
studentTable as student,
classTable as class
where
student.name<>'allen' and class.name<>'math' 
于 2013-03-08T21:22:00.967 回答
0

查询:

SELECT name, course
FROM foo    
WHERE (name, course) NOT IN (SELECT name, course FROM bar);

适用于 MySQL 和 Oracle。对于 Access,这也适用于 MySQL 和 Oracle,您可以将其重写为:

SELECT name, course
FROM foo    
WHERE name NOT IN (SELECT name FROM bar)
AND course NOT IN (SELECT course FROM bar);
于 2015-10-28T15:21:09.600 回答