2013-03-08 4 views
1

Таким образом, я снова возвращаюсь с большим количеством проблем с доступом к MS. У меня есть запрос INSERT INTO с подзапросом, который проверяет, существуют ли данные.Подзапрос MS Access, который возвращает несколько полей

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" 

И следующее может быть в таблице обув:

"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 и выплевывал сообщение ERROR о добавлении первичных ключей и закрывается с выполнением запроса. < - Этого следует ожидать из-за сложного ключа.

+0

Вы говорите: «Везде я посмотрел говорит выше, будет работать ...» вы можете показать ваши источники? – Tony

ответ

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, чтобы показать финальную таблицу. Я также добавил составные первичные ключи к обеим таблицам, чтобы вы могли видеть, что вы не получаете дубликатов вставки.

+0

Спасибо, Тони. Я думаю, это то, что мне нужно, и построенный SQLFiddle помог мне понять это намного лучше. Я буду играть с ним немного больше, чтобы убедиться, но я верю, что это сработает^_^ – divdeamor

+0

, поэтому у меня есть следующий вопрос после игры с SQLfiddle для бит. Я заметил, что если я попытаюсь добавить предложение INSERT INTO над запросом. (Я сделал это, предположив, что могу добавить записи, возвращенные в таблицу), SQL Fiddle возвратил нулевые записи. Возможно, я не понимаю SQLFiddle, но в настоящее время я не в офисе, чтобы проверить свое обнаружение в области доступа – divdeamor

+0

@JohnathonHall - я обновил SQL Fiddle для выполнения 'INSERT'. – Tony

0

Ваш дополнительный запрос возвращает два столбца. вернуть его. Если хотите, где положение, которое может находиться в двух столбцах используйте ИЛИ

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

Edit:

Ваша проблема связана с вопросом нормализации. Предлагаемая редизайн будет заключаться в том, чтобы иметь таблицу для студентов и таблицу для курсов и таблицу, чтобы присоединиться к ним. Пример:

**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' 
+0

Поэтому я предполагаю, что не слежу за всем, что вы сказали. Я хотел бы понять, что просто копировать пасту и быть похожим на то, что она работает. Но с предложением Where в основном есть 2 подзапроса. Возвращает ли это составные значения? – divdeamor

+0

Логично, что и наши вспомогательные запросы говорят одно и то же. Я просто разделил предложение where. Вместо того, чтобы указывать значения WHERE в ('col1', 'col2'), я говорю, где значения в 'col1' и значения в 'col2. Однако, как побочная заметка, причина, по которой вы испытываете трудности, состоит в том, что ваши таблицы не нормализованы. У вас не должно быть избыточных данных в ваших таблицах (например, несколько приложений Johnathan Hall). Я отредактирую свой ответ, чтобы показать, что вам нужно нормализовать их. – jason

+0

@jason. Исходная таблица нормализуется, если первичный ключ является составным именем и курсом. Ваше добавление суррогатных ключей не помогает, на самом деле, если ваш основной ключ classTable_studentTable является studentClassID, тогда вы можете получить несколько строк студента, принимающего тот же класс. – Tony

0

Запрос:

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

работает в MySQL и Oracle.Для доступа, и это также работает в MySQL и Oracle, вы можете переписать его:

SELECT name, course 
FROM foo  
WHERE name NOT IN (SELECT name FROM bar) 
AND course NOT IN (SELECT course FROM bar); 
Смежные вопросы