使用子查询和聚合函数更新sql

时间:2011-04-14 05:17:07

标签: sql sql-server-2005

下面是一个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)

仅供参考...我的选择查询剩下的=工作正常

5 个答案:

答案 0 :(得分:1)

如果选择剩下的查询=返回多条记录,则不会执行。

所以请尽量只获得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 :(得分:1)

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

答案 2 :(得分:1)

我认为您使用的逻辑也需要进行审核。专栏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条款,以便您可以设置它,以便只更新当前年份或上一年,或者您传入的任何年份/期间。这样,您可以确保每年只能为每个帐户获得一条记录。

答案 3 :(得分:0)

您正在尝试使用返回一组行的select语句来设置monthly_calls变量的值。尝试在a.month上使用聚合函数,例如max()。

答案 4 :(得分:0)

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