返回多个字段的MS Access子查询

时间:2013-03-08 21:01:31

标签: sql subquery ms-access-2007

所以我再次回来了更多的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个字段。以上两个字段是我的“bar”数据库中的复合键。

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

3 个答案:

答案 0 :(得分: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后跟SELECT以显示最终表格。我还为两个表添加了复合主键,因此您可以看到没有任何重复插入。

答案 1 :(得分: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' 

答案 2 :(得分: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);
相关问题