Friday, March 9, 2012

Reference an aggregate in where clause

I have two tables that are joined on 1 column.

I want to update one table using an aggregate from the other table.

I could just update all rows even if the aggregate value has not changed, but I wondered if there was a way to only update the records where the aggregate has changed.

I tried this code but assigning the name m to aggreate gives an error

UPDATE t2 SET t2.ColumnB = SELECT MAX(ColumnB) AS m From Table t1

JOIN t2 ON t1.ColumnA = t2.ColumnA

WHERE t2.ColumnB <> m

GROUP BY t1.ColumnA

Niall:

Does this meet your needs?

set nocount on

declare @.t1 table (ColumnA char(1), ColumnB int)
declare @.t2 table (ColumnA char(1), ColumnB int)

insert into @.t1 values ('A', 5)
insert into @.t1 values ('B', null)
insert into @.t1 values ('C', null)
--select * from @.t1

insert into @.t2 values ('A', 3)
insert into @.t2 values ('A', 5)
insert into @.t2 values ('A', 7)
insert into @.t2 values ('B', 2)
--select * from @.t2

set nocount off

update @.t1
set ColumnB = xt.columnb
from @.t1 as yt
inner join
( select t1.ColumnA,
max (t2.columnB) columnB
from @.t1 as t1
inner join @.t2 as t2
on t1.columnA = t2.columnA
group by t1.columnA
) xt
on xt.columnA = yt.columnA

set nocount on

select * from @.t1


-- --
-- Output
-- --


-- (2 row(s) affected)

-- ColumnA ColumnB
-- - --
-- A 7
-- B 2
-- C NULL

|||

Use a subquery - replace the 0 in the isnull calls with blank strings if your ColumnB is character data.

UPDATE Table2 SET ColumnB = t1.MaxB
FROM Table2 t2
INNER JOIN
(SELECT ColumnA, MAX(ColumnB) AS MaxB
FROM Table1
GROUP BY ColumnA) t1 ON t2.ColumnA = t1.ColumnA
WHERE isnull(t2.ColumnB, 0) <> isnull(t1.MaxB, 0)

No comments:

Post a Comment