所以我再次回来了更多的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错误,打开了一个关于附加主键的错误消息并关闭而没有执行查询。 < - 由于复合键,这是预期的。
答案 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);