Reputation: 5636
I have the following tables:
create table Users (
Id int
)
create table Vals1 (
UserId int,
Number int
)
create table Vals2 (
UserId int,
Number int
)
I have values in Vals1
and Vals2
but not a value for every UserId
. What I want to do is, when available, sum the corresponding values between Vals1
and Vals2
.
In this example, assume I have records with Id
1-5 in my User table. So, say I have the following in Vals1
:
UserId Number
1 10
2 15
4 20
And this in Vals2
:
UserId Number
1 30
2 55
3 40
This is what I want as output:
UserId Number
1 40
2 70
3 40
4 20
5 0
My first stab at this produces correct results, but this seems really ugly:
;WITH AllVals1 AS (
SELECT Id, ISNULL(Number, 0) as Number
FROM Users
LEFT JOIN Vals1 ON Id = UserId
), AllVals2 AS (
SELECT Id, ISNULL(Number, 0) as Number
FROM Users
LEFT JOIN Vals2 ON Id = UserId
)
SELECT v1.Id, v1.Number + v2.Number
FROM AllVals1 v1
JOIN AllVals2 v2 ON v1.Id = v2.Id
Is there a more succinct/efficient way of doing this?
Upvotes: 0
Views: 51
Reputation:
Here is much simpler way of doing it, this will only work if you have 1 row per ID in Vals1
and Vals2
table.
SELECT id, COALESCE(v1.Number, 0) + COALESCE(v2.Number, 0) as NumberSum
FROM users u
LEFT OUTER JOIN Vals1 AS v1
ON u.id = v1.userid
LEFT OUTER JOIN vals2 AS v2
ON u.id = v2.userid
If you have more than 1 row per ID in values table than you can add SUM()
and GROUP BY
clause to get rid of multiple rows.
SELECT id
,SUM(COALESCE(v1.Number, 0) + COALESCE(v2.Number, 0))
FROM users u
LEFT OUTER JOIN Vals1 AS v1
ON u.id = v1.userid
LEFT OUTER JOIN vals2 AS v2
ON u.id = v2.userid
GROUP BY id
Upvotes: 2
Reputation: 3867
I suggest to first select all values in a derived temporary table and then calculate the sum grouping by user:
SELECT
tmp.UserId,
sum(tmp.Number) as Number
FROM
(SELECT
UserId,
Number
FROM
Vals1
UNION ALL
SELECT
UserId,
Number
FROM
Vals2) tmp
GROUP BY
tmp.UserId
Upvotes: 0
Reputation: 70528
You can use a left join and then account for the nulls with coalesce or isnull
SELECT users.id, ISNULL(vals1.number,0) + ISNULL(vals2.number,0) as [sum]
FROM users
left join vals1 on vals1.userid = users.id
left join vals2 on vals2.userid = users.id
Upvotes: 1