2009-05-16 19 views
13

Como puedo UPDATE un campo de una tabla con el resultado de una consulta SELECT en Microsoft Access 2007.Uso SELECT dentro de una consulta UPDATE

Aquí está la consulta de selección:

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; 

y aquí está la actualización Consulta:

UPDATE FUNCTIONS 

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

Normalmente puede convertir una consulta SELECT en una consulta de ACTUALIZAR con el clic de un botón en el diseñador de consultas de Access - hay un botón de "tipo de consulta" en la barra de comandos, cuando no está en la vista de SQL. Pruébelo, se ocupa de los requisitos de sintaxis. – Tomalak

+0

Tu comentario parece un chiste. – mammadalius

+4

¿Ves una carita sonriente detrás? No tengo el hábito de escribir comentarios de broma que abarcan varias líneas. – Tomalak

Respuesta

17

Bueno, parece que Access no puede hacer agregados en las consultas de ACTUALIZACIÓN. Pero puede hacer agregados en consultas SELECT. Por lo tanto, cree una consulta con una definición como:

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 

Y guárdelo como YourQuery. Ahora tenemos que trabajar en otra restricción de acceso. Las consultas de actualización no pueden operar en consultas, pero pueden operar en múltiples tablas. Así que vamos a convertir la consulta en una tabla con una consulta de creación de tabla:

SELECT YourQuery.* 
INTO MinOfTax_Code 
FROM YourQuery 

Esto almacena el contenido de la vista en una tabla llamada MinOfTax_Code.Ahora se puede hacer una consulta UPDATE:

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

Haciendo SQL en Access es un poco exagerado, me vería en SQL Server Express Edition para su proyecto!

0

¿Funciona? No probado, pero debe entenderse.

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; 
) 

Básicamente para cada fila de funciones, el sub consulta determina el código fiscal de corriente mínima y establece FUNCTIONS.Func_TaxRef a ese valor. Esto supone que FUNCTIONS.Func_ID es una clave primaria o única.

+0

Acceso diceL: "Las operaciones deben usar una consulta actualizable". – mammadalius

+0

@mammadalius TAKE agregado 2. Vea si eso hace la diferencia. – beach

+0

El acceso dice: "Error de sintaxis" – mammadalius

6

Escribí sobre algunos de los limitations of correlated subqueries en Access/JET SQL hace un tiempo, y tomé nota de la sintaxis para unir varias tablas para SQL ACTUALIZACIONES. Basándome en esa información y en algunas pruebas rápidas, no creo que haya forma de hacer lo que quiera con Access/JET en una sola instrucción SQL UPDATE. Si se pudiera, la declaración podría decir algo como esto:

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 

Alternativamente, Acceso/JET a veces dejar pasar con el ahorro de una sub consulta como una consulta independiente y luego unirse a él en la instrucción UPDATE en una más tradicional camino. Así, por ejemplo, si salvamos la subconsulta SELECT anterior como una consulta independiente llamado FUNCTIONS_TAX, a continuación, la instrucción UPDATE sería:

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

Sin embargo, esto todavía no funciona.

Creo que la única manera de que esto funcione es mover la selección y agregación del valor Tax_Code mínimo fuera de banda. Puede hacer esto con una función VBA, o más fácilmente usando la función Access DBookup. Guarde el GRUPO POR subconsulta anterior para una consulta con nombre FUNCTIONS_TAX separada y volver a escribir la instrucción UPDATE como:

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

Tenga en cuenta que la función DBúsq impide que esta consulta sea utilizado fuera de acceso, por ejemplo a través de OLEDB de JET. Además, el rendimiento de este enfoque puede ser bastante terrible según la cantidad de filas a las que apunte, ya que la subconsulta se ejecuta para cada fila de FUNCIONES (porque, por supuesto, ya no está correlacionada, que es el punto completo en orden para que funcione).

¡Buena suerte!

+1

+1 Agradable, DLookup(), incluso difícil será lento para mesas grandes. Por cierto, parece que la ACTUALIZACIÓN de acceso no permite una combinación en una consulta, pero sí permite una combinación en una tabla (ver mi publicación). Acceso = Raro – Andomar

+1

@ewbi: puede que le interese este artículo de la base de datos, consulta de actualización basada en totales Query Fails (http://support.microsoft.com/kb/116142). – onedaywhen

+0

El acceso también tiene [Funciones Agregadas de Dominio] (https://msdn.microsoft.com/en-us/library/office/aa212172 (v = office.11) .aspx) como 'DAvg',' DMin', 'DMax ',' DCount' y más que pueden ser útiles en esta situación amable. –

1

Tuve un problema similar. Quería encontrar una cadena en una columna y poner ese valor en otra columna en la misma tabla. La instrucción select a continuación encuentra el texto dentro de los parens.

Cuando creé la consulta en Access, seleccioné todos los campos. En la vista SQL para esa consulta, que sustituyó a la mytable.myfield para el campo que quería tener el valor desde el interior de los parens con

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

me encontré con una consulta de creación de tabla. La consulta de make tabla tiene todos los campos con la sustitución anterior y termina con INTO NameofNewTable FROM mytable

0

Quería agregar una respuesta más que utiliza una función VBA, pero hace el trabajo en una declaración SQL. Sin embargo, puede ser 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

Sé que este tema es antiguo, pero pensé que podría agregarle algo.

No pude hacer una actualización con el trabajo Seleccionar consulta usando SQL en MS Access 2010. Usé la sugerencia de Tomalak para que esto funcione. Tenía una captura de pantalla, pero aparentemente soy demasiado newb en este sitio para poder publicarlo.

Pude hacer esto usando la herramienta de diseño de consultas, pero incluso cuando estaba viendo una consulta de actualización exitosa confirmada, Access no pudo mostrarme el SQL que lo hizo posible. Así que no pude hacer que esto funcionara solo con el código SQL.

Creé y guardé mi consulta de selección como una consulta separada. En la herramienta de diseño de consultas, agregué la tabla que estoy tratando de actualizar la consulta de selección que había guardado (puse la clave única en la consulta de selección para que tuviera un enlace entre ellas). Tal como Tomalak sugirió, cambié el Tipo de consulta a Actualizar. Luego tuve que elegir los campos (y designar la tabla) que estaba tratando de actualizar. En los campos "Actualizar a", escribí el nombre de los campos de la consulta de selección que había traído.

Este formato fue exitoso y actualizó la tabla original.

Cuestiones relacionadas