2010-02-03 15 views
16

Cześć wszystkim potężnym SQLsuperherom tam .. Czy ktoś może mnie uratować przed nieuchronną katastrofą i ruiną?Wstaw rekord do tabeli, jeśli wpis nie istnieje w innej tabeli - z dodatkowym wykręceniem

Pracuję z programem Microsoft Access SQL. Chciałbym wybrać rekordy w jednej tabeli (tabela 1), które nie pojawiają się w innym (tabela 2) .., a następnie wstawić nowe rekordy do tabeli 2, które są oparte na rekordach w tabeli 1, w następujący sposób:

[tabela 1] file_index: nazwa pliku

[Tabela 2] file_index: celeb_name

chcę:

Zaznacz wszystkie rekordy z Tabela1 gdzie [nazwa pliku] jest jak AUD i której odpowiada [file_index] wartość nie istnieć w tabela2 z polem [celeb_name] = 'Audrey Hepburn'

Z tej selekcji Następnie chcę, aby wstawić nowy rekord do [Table2]

[file_index] = [Tabela1]. [file_index ] [celeb_name] = 'Audrey'

Istnieje jeden do wielu między [file_index] w tabeli 1. [] i [tabeli2] jeden rekord [Tabela 1], w wielu [tabeli2].

Wielkie dzięki

Odpowiedz

14

Czy to zrobi? Oczywiście dodaj nawiasy kwadratowe i inne. Nie za bardzo w Access.

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

Tor - naprawdę jesteś potężnym bóg SQL, jak sugeruje twoje imię. Dziękuję bardzo. Udało się – bonzo46

+0

NOT IN nie jest dobrze zoptymalizowany w Jet/ACE, ponieważ często nie będzie korzystać z indeksów po obu stronach (lub po obu stronach w niektórych przypadkach). AND OUT JOIN będzie o wiele bardziej wiarygodny, ponieważ zawsze używa indeksów, jeśli połączone pola są indeksowane. –

+4

@ David-W-Fenton - Każdy, kto używa Accessa i oczekuje wydajności, powinien naprawdę wyglądać gdzie indziej ...;) –

0

W oryginalnym pytaniu zmodyfikowałem moje nazwy tabel i pól oraz wstawiłem nawiasy kwadratowe, aby ułatwić czytanie.

Poniżej znajduje się ostateczna instrukcja SQL, która działała w formacie MS Access. Fantastyczny wynik, jeszcze raz dzięki 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*")); 
+0

Niestety, moja pierwsza edycja była całkowicie błędna, po prostu nieostrożne tłumaczenie z mojej strony. Właśnie naprawiłem to i zastąpiłem moje zapytanie powyższym. – bonzo46

1

Jak powiedziałem w komentarzach, NOT IN nie jest dobrze zoptymalizowany przez Jet/ACE i jest to zwykle bardziej efektywne w użyciu zewnętrznego JOIN. W tym przypadku, ponieważ trzeba filtrować na zewnętrznej stronie przyłączyć, trzeba podkwerenda:

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; 

(które nie mogą być dokładnie prawo - jestem straszny z pisania SQL ręcznie, w szczególności uzyskanie składni JOIN z prawej)

Muszę jednak powiedzieć, że zastanawiam się, czy spowoduje to wstawienie zbyt wielu rekordów (i ta sama rezerwacja dotyczy wersji NOT IN).

Powiązane problemy