2010-02-03 12 views
16

Ciao a tutti voi potenti SQLsuperheros là fuori ... Qualcuno può salvarmi da un disastro imminente e rovinare?Inserisci record nella tabella se la voce non esiste in un'altra tabella con un tocco in più

Sto lavorando con Microsoft Access SQL. Vorrei selezionare i record in una tabella (tabella1) che non compaiono in un'altra (tabella2) .. e quindi inserire nuovi record in tabella2 basati sui record di tabella1, come segue:

[tabella1] file_index: filename

[table2] file_index: celeb_name

voglio:

selezionare tutti i record da table1 dove [nome] è come aud e la cui corrispondente [file_index] valore non esiste in table2 con con il campo [celeb_name] = 'Audrey Hepburn'

Con la selezione allora voglio inserire un nuovo record nella [table2]

[file_index] = [table1]. [file_index ] [celeb_name] = 'Audrey Hepburn'

C'è un uno a molti tra [file_index] in [table1] e [table2] un record in [table1], a molti in [table2].

Molte grazie

risposta

14

Sarà questo fare? Ovviamente aggiungi delle parentesi quadre e altro. Non troppo in Access me stesso.

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 - sei veramente un dio SQL potente, come suggerisce il tuo nome. Grazie mille. Ha funzionato – bonzo46

+0

NOT IN non è ottimizzato in Jet/ACE, poiché spesso non utilizza gli indici su entrambi i lati (o su entrambi i lati in alcuni casi). E OUTER JOIN diventerà molto più affidabile, poiché utilizza sempre indici se i campi uniti sono indicizzati. –

+4

@ David-W-Fenton - Chiunque utilizzi Access e si aspetta che le prestazioni facciano davvero attenzione altrove;;) –

0

Nella domanda iniziale che avevo modificato il mio nomi di tabella e di campo e inseriti in parentesi quadre per rendere più facile da leggere.

Di seguito è riportata l'istruzione SQL finale che ha funzionato in formato MS Access. Risultato fantastico, grazie ancora 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

Spiacente, la mia modifica iniziale era completamente sbagliata, solo una traduzione incurante da parte mia. Ho appena riparato e sostituito la mia domanda con quanto sopra. – bonzo46

1

Come ho detto nei commenti, NON IN non è ben ottimizzato da Jet/ACE e di solito è più efficiente utilizzare un outer join. In questo caso, perché è necessario filtrare sul lato esterno del join, avrete bisogno di un sottoquery:

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; 

(che potrebbe non essere esattamente a destra - io sono terribile con la scrittura SQL a mano, in particolare ottenendo la sintassi JOIN corretta)

Devo dire, però, che mi chiedo se questo inserirà troppi record (e la stessa prenotazione si applica alla versione NOT IN).

Problemi correlati