update a sql using subquery and aggregate function
Below is a SQL query where I am getting the error
开发者_如何学编程returns more than 1 value
Query:
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)
FYI... my select query which is left of = is working fine
If you select query which is left of = returns multiple records then it will not be executed.
So please try to get only 1 record out of that.
Only one record can be updates at a time using this update statement, so you must make sure that only one record is returned by that query.
Try this.
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)
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
I think the logic you're using needs to be reviewed as well. The column annual_calls
- does it get updated once a year, or is it updated at the end of every month? The reason I ask is if this were for a new system with only 6 months worth of calls, the monthly_calls
field would be set to a value of approximately half of what it should be.
I would suggest also renaming monthly_calls
to avg_monthly_calls
or something more meaningful because if someone were to come in, look at your database schema and try to work out what is what, they might think that field holds total monthly calls or expected monthly calls.
As for the statement to update the data - without seeing any sort of data, here's a neater way of using an UPDATE
statement without subselects:
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
This basically takes care of the subselect by including a FROM
clause in the UPDATE
statement. That way you can join and update all at once.
Edit: I would also add in a WHERE
clause so you can set it so you update only the current year, or the previous year, or whatever year/period you pass in. That way, you ensure you only get one record for each account for each year.
You are trying to set monthly_calls variable's value by using a select statement that returns a set of rows. Try using an aggregate function on a.month like max().
Standard SQL requires scalar subqueries, which in this case is arguably simpler than joins anyhow:
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
);
精彩评论