Вставить запись в таблицу, если запись не существует в другой таблице - с дополнительным поворотом - PullRequest
16 голосов
/ 03 февраля 2010

Привет всем вам могучим SQLsuperheros там .. Кто-нибудь может спасти меня от неизбежной катастрофы и разорения?

Я работаю с Microsoft Access SQL. Я хотел бы выбрать записи в одной таблице (таблица1), которые не отображаются в другой (таблица2) .., а затем вставить в таблицу2 новые записи, основанные на записях в таблице1, следующим образом:

[table1] file_index: имя файла

[table2] Индекс_файла: имя_символа

Я хочу:

Выбрать все записи из таблицы1, где [имя файла] похоже на aud и чье соответствующее значение [file_index] не существует в таблице 2 с полем [celeb_name] = 'Одри Хепберн'

После этого выбора я хочу вставить новую запись в [table2]

[file_index] = [table1]. [File_index] [знаменитость] = 'Одри Хепберн'

Между [file_index] в [table1] и [table2] существует отношение один ко многим. Одна запись в [table1], для многих в [table2].

Большое спасибо

Ответы [ 3 ]

15 голосов
/ 03 февраля 2010

Будет ли это делать? Очевидно, добавить несколько квадратных скобок и прочее. Не слишком в себе доступ.

INSERT INTO table2 (file_index, celeb_name)
SELECT file_index, 'Audrey Hepburn'
FROM table1
WHERE filename = 'aud'
  AND file_index NOT IN (SELECT DISTINCT file_index 
                         FROM table2 
                         WHERE celeb_name = 'Audrey Hepburn')
2 голосов
/ 04 февраля 2010

Как я уже говорил в комментариях, NOT IN недостаточно оптимизирован для Jet / ACE, и обычно более эффективно использовать OUTER JOIN. В этом случае, поскольку вам нужно отфильтровать внешнюю сторону объединения, вам потребуется подзапрос:

  INSERT INTO photos_by_celebrity ( ORIG_FILE_INDEX, celebrity_name )
  SELECT tblOriginal_Files.ORIG_FILE_INDEX, 'Audrey Hepburn'
  FROM tblOriginal_Files 
    LEFT JOIN (SELECT DISTINCT ORIG_FILE_INDEX  
                  FROM photos_by_celebrity 
                  WHERE celebrity_name = 'Audrey Hepburn') AS Photos
    ON tblOriginal_Files.ORIG_FILE_INDEX = Photos.ORIG_FILE_INDEX
  WHERE Photos.ORIG_FILE_INDEX Is Null;

(это может быть не совсем верно - я ужасно пишу на SQL вручную, особенно с правильным синтаксисом JOIN)

Я должен сказать, однако, что мне интересно, вставит ли это слишком много записей (и то же самое резервирование применяется к версии NOT IN).

0 голосов
/ 04 февраля 2010

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

Ниже приведен последний оператор SQL, работавший в формате MS Access.Потрясающий результат, еще раз спасибо Tor !!

INSERT INTO photos_by_celebrity ( ORIG_FILE_INDEX, celebrity_name )

SELECT tblOriginal_Files.ORIG_FILE_INDEX, 'Audrey Hepburn' AS Expr1

FROM tblOriginal_Files

WHERE (((tblOriginal_Files.ORIG_FILE_INDEX) Not In (SELECT DISTINCT ORIG_FILE_INDEX 

                         FROM photos_by_celebrity  

                         WHERE celebrity_name = 'Audrey Hepburn')) AND ((tblOriginal_Files.ORIGINAL_FILE) Like "*aud*"));
...