обновить SQL с помощью подзапроса и агрегатной функции - PullRequest
1 голос
/ 14 апреля 2011

Ниже приведен SQL-запрос, в котором я получаю сообщение об ошибке

возвращает более 1 значения

Запрос:

update Tab2 
set monthly_calls = 
    (select a.month 
     from 
          (select accountid, max(annual_calls)/12 as month 
           from cpo 
           group by accountid) a 
     inner join tab2 on tab2.accountid = a.accountid)

К вашему сведению ... мой запрос select, от которого осталось =, работает нормально

Ответы [ 5 ]

1 голос
/ 14 апреля 2011

Я думаю, что используемая вами логика также нуждается в пересмотре.Столбец annual_calls - обновляется ли он раз в год или в конце каждого месяца?Причина, по которой я спрашиваю, заключается в том, что если бы это было для новой системы с вызовами на 6 месяцев, в поле monthly_calls было бы установлено значение примерно вдвое меньше, чем должно быть.

Я бы также предложилпереименуйте monthly_calls в avg_monthly_calls или что-то более значимое, потому что, если кто-то придет, посмотрите на схему вашей базы данных и попытайтесь выяснить, что к чему, они могут подумать, что в этом поле содержатся общие ежемесячные вызовы или ожидаемые ежемесячные вызовы.

Что касается оператора для обновления данных - без просмотра каких-либо данных, вот более аккуратный способ использования оператора UPDATE без подвыборов:

UPDATE
    Tab2
SET
    monthly_calls = MAX(annual_calls) / 12
FROM
    CPO INNER JOIN Tab2 ON CPO.accountid = Tab2.accountid
WHERE
    YEAR([Tab2.DateField]) = @YearToUpdate
GROUP BY
    CPO.accountid

Это в основном заботится о подвыборкевключив предложение FROM в оператор UPDATE.Таким образом, вы можете присоединиться и обновлять все сразу.

Редактировать: Я бы также добавил предложение WHERE, чтобы вы могли установить его так, чтобы вы обновляли только текущий год, или предыдущий год, или любой другой год/ период, в который вы проходите. Таким образом, вы гарантируете, что получаете только одну запись для каждой учетной записи за каждый год.

1 голос
/ 14 апреля 2011

Если вы выберете запрос, от которого осталось = возвращает несколько записей, он не будет выполнен.

Поэтому, пожалуйста, постарайтесь получить только 1 запись из этого.

Только одна запись может быть обновлена ​​за один раз с помощью этого оператора обновления, поэтому вы должны убедиться, что по этому запросу возвращается только одна запись.

Попробуйте это.

update Tab2 
set monthly_calls = 
    (select top 1 a.month 
     from 
          (select accountid, max(annual_calls)/12 as month 
           from cpo 
           group by accountid) a 
     inner join tab2 on tab2.accountid = a.accountid)
1 голос
/ 14 апреля 2011
update Tab2 
set monthly_calls = a.month 
from 
     (select accountid, max(annual_calls)/12 as month 
      from cpo 
      group by accountid) a 
inner join tab2 on tab2.accountid = a.accountid
0 голосов
/ 14 апреля 2011

Стандартный SQL требует скалярных подзапросов, что в данном случае, возможно, проще, чем объединение в любом случае:

UPDATE Tab2 
   SET monthly_calls = (
                        SELECT MAX(annual_calls) / 12
                          FROM cpo 
                         WHERE tab2.accountid = cpo.accountid
                       )
 WHERE EXISTS (
               SELECT *
                 FROM cpo
                WHERE tab2.accountid = cpo.accountid
              );
0 голосов
/ 14 апреля 2011

Вы пытаетесь установить значение переменной month_calls с помощью оператора select, который возвращает набор строк.Попробуйте использовать агрегатную функцию в a.month, например, max ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...