Использовать SELECT внутри запроса обновления

как я могу UPDATE поле таблицы с результатом SELECT запрос в Microsoft Access 2007.

вот запрос Select:

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;

и вот запрос обновления:

UPDATE FUNCTIONS

 SET FUNCTIONS.Func_TaxRef = [Result of Select query]

6 ответов


Ну, похоже, что Access не может выполнять агрегаты в запросах обновления. Но он может делать агрегаты в SELECT запросах. Поэтому создайте запрос с определением типа:

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

и сохраните его как YourQuery. Теперь мы должны обойти еще одно ограничение доступа. Запросы обновления не могут работать с запросами, но они могут работать с несколькими таблицами. Поэтому давайте превратим запрос в таблицу с запросом Make Table:

SELECT YourQuery.* 
INTO MinOfTax_Code
FROM YourQuery

Это хранит содержимое в таблицу MinOfTax_Code. Теперь вы можете сделать запрос обновления:

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

выполнение SQL в Access немного растягивается, я бы посмотрел в Sql Server Express Edition для вашего проекта!


я писал о некоторых ограничения коррелированных подзапросов в Access / JET SQL некоторое время назад и отметил синтаксис для объединения нескольких таблиц для обновлений SQL. Основываясь на этой информации и быстром тестировании, я не верю, что есть способ сделать то, что вы хотите с Access/JET в одном операторе обновления SQL. Если вы могли, в заявлении было написано что-то вроде этого:

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 иногда позволит вам уйти с сохранением подзапрос как отдельный запрос, а затем присоединиться к нему в инструкции UPDATE более традиционным способом. Так, например, если мы сохранили подзапрос SELECT выше как отдельный запрос с именем FUNCTIONS_TAX, то инструкция UPDATE будет:

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

однако это все еще не работает.

Я считаю, что единственный способ сделать эту работу-переместить выбор и агрегацию минимального значения Tax_Code вне диапазона. Вы можете сделать это с помощью функции VBA или более легко с помощью функции доступ к функции dlookup. Сохраните группу по подзапросу выше в отдельный запрос с именем FUNCTIONS_TAX и перепишите инструкцию UPDATE как:

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

обратите внимание, что функция DLookup предотвращает использование этого запроса вне доступа, например через JET OLEDB. Кроме того, производительность этого подхода может быть довольно ужасной в зависимости от того, сколько строк вы нацеливаете, поскольку подзапрос выполняется для каждой строки функций (потому что, конечно, это больше не коррелированный, что является целым пунктом для того, чтобы он работал).

удачи!


у меня была похожая проблема. Я хотел найти строку в одном столбце и поместить это значение в другой столбец в той же таблице. Инструкция select ниже находит текст внутри parens.

когда я создал запрос в Access я выбрал все поля. В представлении SQL для этого запроса Я заменил mytable.myfield для поля, которое я хотел иметь значение изнутри parens с

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

Я запустил запрос make table. Запрос make table содержит все поля с вышеуказанная подстановка и заканчивается на INTO NameofNewTable FROM mytable


это работает? Непроверенный, но должен получить точку зрения.

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

в основном для каждой строки в функциях подзапрос определяет минимальный текущий налоговый код и устанавливает функции.Func_TaxRef к этому значению. Это предполагает, что функции.Func_ID является первичным или уникальным ключом.


Я хотел добавить еще один ответ, который использует функцию VBA, но он выполняет работу в одном операторе SQL. Хотя, это может быть медленно.

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)

Я знаю, что эта тема старая, но я думал, что могу что-то добавить к ней.

Я не смог сделать обновление с помощью Select query work с использованием SQL в MS Access 2010. Я использовал предложение Томалака, чтобы сделать эту работу. У меня был скриншот, но, по-видимому, слишком много нового на этом сайте, чтобы иметь возможность опубликовать его.

Я смог сделать это с помощью инструмента проектирования запросов, но даже когда я смотрел на подтвержденный успешный запрос обновления, Access не смог показать мне SQL, который сделал это произойдет. Поэтому я не мог заставить это работать только с кодом SQL.

Я создал и сохранил запрос select как отдельный запрос. В инструменте проектирования запросов я добавил таблицу, которую пытаюсь обновить сохраненный запрос select (я поместил уникальный ключ в запрос select, чтобы между ними была связь). Как и предполагал Томалак, я изменил тип запроса на Update. Затем мне просто нужно было выбрать поля (и обозначить таблицу), которые я пытался обновить. В полях" обновить до", Я ввел имя полей из запроса select, который я привел.

этот формат был успешным и обновил исходную таблицу.