web-dev-qa-db-fra.com

Utilisez SELECT dans une requête UPDATE

Comment puis-je UPDATE un champ d'une table avec le résultat d'une requête SELECT dans Microsoft Access 2007.

Voici la requête choisie:

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;

Et voici la requête de mise à jour:

UPDATE FUNCTIONS

 SET FUNCTIONS.Func_TaxRef = [Result of Select query]
13
mammadalius

Eh bien, il semble qu'Access ne puisse pas effectuer d'agrégats dans les requêtes UPDATE. Mais il peut faire des agrégats dans les requêtes SELECT. Alors créez une requête avec une définition comme:

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

Et enregistrez-le sous YourQuery. Nous devons maintenant contourner une autre restriction d'accès. Les requêtes UPDATE ne peuvent pas fonctionner sur des requêtes, mais sur plusieurs tables. Nous allons donc transformer la requête en une table avec une requête Make Table:

SELECT YourQuery.* 
INTO MinOfTax_Code
FROM YourQuery

Ceci stocke le contenu de la vue dans une table appelée MinOfTax_Code. Maintenant, vous pouvez faire une requête UPDATE:

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

Faire SQL dans Access est un peu exagéré, je regarderais dans SQL Server Express Edition pour votre projet!

18
Andomar

J'ai écrit sur certaines des limitations des sous-requêtes corrélées dans Access/JET SQL il y a quelque temps, et noté la syntaxe permettant de joindre plusieurs tables pour les mises à jour SQL. Sur la base de ces informations et de quelques tests rapides, je ne pense pas qu'il soit possible de faire ce que vous voulez avec Access/JET dans une seule instruction SQL UPDATE. Si vous le pouviez, la déclaration se lirait comme suit:

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

Access/JET peut également vous laisser parfois tenter de sauvegarder une sous-requête en tant que requête distincte, puis de la joindre à l'instruction UPDATE de manière plus traditionnelle. Ainsi, par exemple, si nous sauvegardions la sous-requête SELECT ci-dessus en tant que requête distincte nommée FUNCTIONS_TAX, l'instruction UPDATE serait:

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

Cependant, cela ne fonctionne toujours pas.

Je pense que la seule manière de faire fonctionner ce travail est de déplacer la sélection et l’agrégation de la valeur minimale de Tax_Code hors bande. Vous pouvez le faire avec une fonction VBA ou plus facilement en utilisant la fonction Access DLookup. Enregistrez la sous-requête GROUP BY ci-dessus dans une requête distincte nommée FUNCTIONS_TAX et réécrivez l'instruction UPDATE en tant que:

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

Notez que la fonction DLookup empêche l'utilisation de cette requête en dehors d'Access, par exemple via JET OLEDB. En outre, les performances de cette approche peuvent être très mauvaises en fonction du nombre de lignes que vous ciblez, car la sous-requête est exécutée pour chaque ligne FUNCTIONS pour que cela fonctionne).

Bonne chance!

6
ewbi

J'avais un problème similaire. Je voulais trouver une chaîne dans une colonne et mettre cette valeur dans une autre colonne de la même table. L'instruction select ci-dessous trouve le texte à l'intérieur des parenthèses.

Lorsque j'ai créé la requête dans Access, j'ai sélectionné tous les champs. Dans la vue SQL de cette requête, j'ai remplacé mytable.myfield par le champ pour lequel je voulais avoir la valeur à l'intérieur des parenthèses avec 

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

J'ai exécuté une requête make table. La requête make table contient tous les champs avec la substitution ci-dessus et se termine par INTO NameofNewTable FROM mytable

1
Spud_Gasket

Est-ce que ça marche? Non testé mais devrait faire passer le message.

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

En gros, pour chaque ligne de FUNCTIONS, la sous-requête détermine le code de taxe actuel minimum et définit FUNCTIONS.Func_TaxRef sur cette valeur. Ceci suppose que FUNCTIONS.Func_ID est une clé primaire ou unique.

0
beach

Je voulais ajouter une réponse supplémentaire utilisant une fonction VBA, mais le travail est effectué dans une instruction SQL. Bien que cela puisse être lent.

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
Bobort

Je sais que ce sujet est ancien, mais je pensais pouvoir y ajouter quelque chose.

Je ne pouvais pas utiliser une requête de mise à jour avec Select avec SQL dans MS Access 2010. J'ai utilisé la suggestion de Tomalak pour que cela fonctionne. J'avais une capture d'écran, mais je suis apparemment trop novice sur ce site pour pouvoir la publier.

J'ai pu le faire à l'aide de l'outil de conception de requête, mais même si je cherchais une requête de mise à jour confirmée, Access n'a pas été en mesure de me montrer le code SQL qui a permis son exécution. Je ne pouvais donc pas faire fonctionner ce logiciel avec le code SQL seul.

J'ai créé et enregistré ma requête sélectionnée en tant que requête distincte. Dans l'outil de conception de requête, j'ai ajouté le tableau sur lequel je tente de mettre à jour la requête de sélection que j'avais sauvegardée (j'ai mis la clé unique dans la requête de sélection afin qu'il y ait un lien entre elles). Comme Tomalak l'avait suggéré, j'ai changé le type de requête en mise à jour. Il me suffisait alors de choisir les champs (et de désigner la table) que j'essayais de mettre à jour. Dans les champs "Mettre à jour", j'ai saisi le nom des champs de la requête sélectionnée que j'avais apportée.

Ce format a réussi et a mis à jour le tableau d'origine.

0
sbaer