MS Access Subquery that returns Multiple Fields

2019-08-04 11:00发布

So im back again with more MS Access problems. I have a INSERT INTO query with a subquery that checks to see if the data already exists.

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

to expound a little on what i am trying to accomplish since the above doesn't work.

I am trying to select composite keys that do not exist already in the table bar. For example the following could be stored in the table bar:

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

And the following could be in the table foo:

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

The query should return the following:

"John Doe", "Science"

Everywhere i have looked says the above will work and im sure it does in theory. The problem i run into is with MS Access... When i attempt to run this query it pops up stating that the subquery will return multiple fields. Indeed it should as that is what i want it do do is return 2 fields that i can compare the other 2 fields. The above 2 fields are a composite key in my "bar" database.

For more background I am using MS Excel 2007 and MS Access 2007. The Excel is being used to input data and running the query through VB script. I am trying to make a subquery that checks for fields already in the final database because i ran into the error of MS Access opening up and spitting out a ERROR message about appending primary keys and closes with out executing the query. <-- That is to be expected due to the composite key.

3条回答
Rolldiameter
2楼-- · 2019-08-04 11:24

your sub query is returning two columns. make it return one. If want a where clause that can be in two columns, use OR

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

Edit:

Your problem stems from a normalization issue. A suggested redesign would be to have a table for students and a table for courses and a table to join them. Example:

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

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

**classTable_studentTable**
studentClassID
studentID
classID

Each student can have many classes and each class can have many students. It's a many to many relationship that is normalized by using the join table.

Now, if you wanted to do a query like your asking:

Select *.student, *.class
from
studentTable as student,
classTable as class
where
student.name<>'allen' and class.name<>'math' 
查看更多
何必那么认真
3楼-- · 2019-08-04 11:29

Use LEFT JOIN and look for NULL values:

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

I've updated the SQLFiddle to include the INSERT followed by a SELECT to show the final table. I've also added composite primary keys to both tables so you can see that you do not get any duplicate inserts.

查看更多
够拽才男人
4楼-- · 2019-08-04 11:43

The query:

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

works in MySQL and Oracle. For Access, and this also works in MySQL and Oracle, you can rewrite it to:

SELECT name, course
FROM foo    
WHERE name NOT IN (SELECT name FROM bar)
AND course NOT IN (SELECT course FROM bar);
查看更多
登录 后发表回答