2009-05-16 19 views
13

Come posso UPDATE un campo di una tabella con il risultato di una query SELECT in Microsoft Access 2007.Utilizzare SELECT all'interno di una query di UPDATE

Ecco la query di selezione:

SELECT Min(TAX.Tax_Code) AS MinOfTax_Code 
FROM TAX, FUNCTIONS 

WHERE (((FUNCTIONS.Func_Pure)<=[Tax_ToPrice]) AND ((FUNCTIONS.Func_Year)=[Tax_Year])) 

GROUP BY FUNCTIONS.Func_ID; 

Ed ecco l'aggiornamento Richiesta:

UPDATE FUNCTIONS 

SET FUNCTIONS.Func_TaxRef = [Result of Select query] 
+0

In genere è possibile trasformare una query SELECT in una query UPDATE con il clic di un pulsante in Progettazione query di Access - è presente un pulsante "tipo query" nella barra dei comandi, quando non si è in visualizzazione SQL. Provalo, si prende cura di qualsiasi requisito di sintassi. – Tomalak

+0

Il tuo commento sembra uno scherzo. – mammadalius

+4

Vedi uno smile dietro? Non ho l'abitudine di scrivere commenti di battute su più righe. – Tomalak

risposta

17

Bene, sembra che Access non possa fare aggregazioni nelle query UPDATE. Ma può fare aggregati nelle query SELECT. Quindi creare una query con una definizione del tipo:

SELECT func_id, min(tax_code) as MinOfTax_Code 
FROM Functions 
INNER JOIN Tax 
ON (Functions.Func_Year = Tax.Tax_Year) 
AND (Functions.Func_Pure <= Tax.Tax_ToPrice) 
GROUP BY Func_Id 

E salvarlo come YourQuery. Ora dobbiamo aggirare un'altra restrizione di accesso. Le query UPDATE non possono operare su query, ma possono operare su più tabelle. Quindi cerchiamo di trasformare la query in una tabella con una query di creazione tabella:

SELECT YourQuery.* 
INTO MinOfTax_Code 
FROM YourQuery 

Questo memorizza il contenuto della vista in una tabella chiamata MinOfTax_Code.Ora si può fare una query UPDATE:

UPDATE MinOfTax_Code 
INNER JOIN Functions ON MinOfTax_Code.func_id = Functions.Func_ID 
SET Functions.Func_TaxRef = [MinOfTax_Code].[MinOfTax_Code] 

Fare SQL in Access è un po 'di un tratto, mi piacerebbe guardare in SQL Server Express Edition per il vostro progetto!

0

Funziona? Non testato, ma dovrebbe arrivare al punto.

UPDATE FUNCTIONS 
SET Func_TaxRef = 
(
    SELECT Min(TAX.Tax_Code) AS MinOfTax_Code 
    FROM TAX, FUNCTIONS F1 
    WHERE F1.Func_Pure <= [Tax_ToPrice] 
    AND F1.Func_Year=[Tax_Year] 
    AND F1.Func_ID = FUNCTIONS.Func_ID 
    GROUP BY F1.Func_ID; 
) 

Fondamentalmente per ogni riga FUNZIONI, subquery determina il codice minimo fiscale corrente e imposta FUNCTIONS.Func_TaxRef a tale valore. Ciò presuppone che FUNCTIONS.Func_ID sia una chiave primaria o univoca.

+0

L'accesso dice: "Le operazioni devono utilizzare una query aggiornabile". – mammadalius

+0

@mammadalius aggiunto TAKE 2. Verifica se questo fa la differenza. – beach

+0

L'accesso dice: "Errore di sintassi" – mammadalius

6

Ho scritto su alcuni degli limitations of correlated subqueries in Access/JET SQL qualche istante indietro e ho annotato la sintassi per l'unione di più tabelle per gli UPDATE SQL. Sulla base di queste informazioni e alcuni test rapidi, non credo che ci sia un modo per fare ciò che vuoi con Access/JET in una singola istruzione SQL UPDATE. Se si potesse, la dichiarazione dovrebbe leggere qualcosa di simile:

UPDATE FUNCTIONS A 
INNER JOIN (
    SELECT AA.Func_ID, Min(BB.Tax_Code) AS MinOfTax_Code 
    FROM TAX BB, FUNCTIONS AA 
    WHERE AA.Func_Pure<=BB.Tax_ToPrice AND AA.Func_Year= BB.Tax_Year 
    GROUP BY AA.Func_ID 
) B 
ON B.Func_ID = A.Func_ID 
SET A.Func_TaxRef = B.MinOfTax_Code 

In alternativa, Accesso/JET a volte consente di ottenere via con il salvataggio di una subquery come una query separata e poi unirlo nell'istruzione UPDATE in un più tradizionale modo. Così, per esempio, se abbiamo salvato la subquery seleziona sopra come una query separata denominata FUNCTIONS_TAX, quindi l'istruzione UPDATE sarebbe:

UPDATE FUNCTIONS 
INNER JOIN FUNCTIONS_TAX 
ON FUNCTIONS.Func_ID = FUNCTIONS_TAX.Func_ID 
SET FUNCTIONS.Func_TaxRef = FUNCTIONS_TAX.MinOfTax_Code 

Tuttavia, questo ancora non funziona.

Credo che l'unico modo per farlo funzionare sia spostare la selezione e l'aggregazione del valore Tax_Code minimo out-of-band. È possibile farlo con una funzione VBA o più facilmente utilizzando la funzione Access DLookup. Salvare il GROUP BY subquery sopra per una query denominata FUNCTIONS_TAX separata e riscrivere l'istruzione UPDATE come:

UPDATE FUNCTIONS 
SET Func_TaxRef = DLookup(
    "MinOfTax_Code", 
    "FUNCTIONS_TAX", 
    "Func_ID = '" & Func_ID & "'" 
) 

Si noti che la funzione DLookup impedisce questa query venga utilizzato al di fuori di accesso, per esempio tramite JET OLE DB. Inoltre, le prestazioni di questo approccio possono essere piuttosto terribili a seconda del numero di righe a cui sei indirizzato, poiché la sottoquery viene eseguita per ogni riga FUNCTIONS (perché, ovviamente, non è più correlata, ovvero l'intero punto in ordine per farlo funzionare).

Buona fortuna!

+1

+1 Nice, DLookup(), anche difficile sarà lento per i grandi tavoli. Sembra che Access UPDATE non permetta un join su una query, ma consente un join su una tabella (vedi il mio post). Access = Weird – Andomar

+1

@ewbi: potresti essere interessato a questo articolo della Knowledge Base, Query di aggiornamento basata sui totali Query Fails (http://support.microsoft.com/kb/116142). – onedaywhen

+0

L'accesso ha anche [Funzioni di aggregazione dei domini] (https://msdn.microsoft.com/en-us/library/office/aa212172 (v = office.11) .aspx) come 'DAvg',' DMin', 'DMax ',' DCount' e altro che può essere utile in questa situazione gentile. –

1

Ho avuto un problema simile. Volevo trovare una stringa in una colonna e mettere quel valore in un'altra colonna nella stessa tabella. L'istruzione select qui sotto trova il testo all'interno dei parens.

Quando ho creato la query in Access ho selezionato tutti i campi. Nella visualizzazione SQL per tale query, ho sostituito il mytable.myfield per il campo volevo avere il valore all'interno delle parentesi con

SELECT Left(Right(OtherField,Len(OtherField)-InStr((OtherField),"(")), 
      Len(Right(OtherField,Len(OtherField)-InStr((OtherField),"(")))-1) 

ho eseguito una query di creazione tabella. La query di creazione tabella ha tutti i campi con la sostituzione di cui sopra e termina con INTO NameofNewTable FROM mytable

0

Desidero aggiungere un'altra risposta che utilizza una funzione VBA, ma esegue il lavoro in un'unica istruzione SQL. Tuttavia, può essere lento.

UPDATE FUNCTIONS 
SET FUNCTIONS.Func_TaxRef = DLookUp("MinOfTax_Code", "SELECT 
FUNCTIONS.Func_ID,Min(TAX.Tax_Code) AS MinOfTax_Code 
FROM TAX, FUNCTIONS 
WHERE (((FUNCTIONS.Func_Pure)<=[Tax_ToPrice]) AND ((FUNCTIONS.Func_Year)=[Tax_Year])) 
GROUP BY FUNCTIONS.Func_ID;", "FUNCTIONS.Func_ID=" & Func_ID) 
0

So che questo argomento è vecchio, ma ho pensato di aggiungere qualcosa.

Non è stato possibile eseguire un aggiornamento con il lavoro di query Select utilizzando SQL in MS Access 2010. Ho utilizzato il suggerimento di Tomalak per farlo funzionare. Avevo uno screenshot, ma sono apparentemente troppo di un newb su questo sito per poterlo postare.

Sono stato in grado di farlo utilizzando lo strumento Query Design, ma anche se stavo guardando una query di aggiornamento confermata, Access non era in grado di mostrarmi l'SQL che l'ha fatto accadere. Quindi non ho potuto farlo funzionare solo con il codice SQL.

Ho creato e salvato la mia query di selezione come una query separata. Nello strumento Query Design, ho aggiunto la tabella Sto tentando di aggiornare la query di selezione che avevo salvato (ho inserito la chiave univoca nella query di selezione in modo da avere un collegamento tra di loro). Proprio come Tomalak mi aveva suggerito, ho cambiato il tipo di query in aggiornamento. Ho quindi dovuto scegliere i campi (e designare la tabella) che stavo cercando di aggiornare. Nei campi "Aggiorna a", ho digitato il nome dei campi dalla query selezionata che avevo inserito.

Questo formato ha avuto successo e aggiornato la tabella originale.

Problemi correlati