SQL Compare data from two joined tables
-
06-02-2021 - |
Question
i used SQL Server, and have two joined table
Select b.team, SUM(a.total) FROM data1 A
INNER JOIN team b ON a.teamID = b.teamID
WHERE month = 1 and year = 2019
GROUP by team
second one is like this
Select b.team, SUM(c.total) FROM data2 C
INNER JOIN team b ON c.teamID = b.teamID
WHERE Date BETWEEN '2019-01-01' AND '2019-01-31'
GROUP by team
and the result will be :
Data 1 Data 2
TEAM | Total TEAM | Total
Team 1 | 5 Team 1 | 4
Team 2 | 3 Team 2 | 3
Team 3 | 8 Team 3 | 9
i wanted to create query to get result like this :
Team | Total
Team 1 | 1
Team 3 | -1
Solution
There's a bit of ambiguity in the original spec, as in the example, each team is in both lists, yet it isn't clear whether this will always be the case. If it isn't, should a missing value be treated as zero, or does it imply the team should be dropped from the results, like when the net total is zero?
If the latter, an inner join would be appropriate:
SELECT d1.Team, Total = d1.Total1 - d2.Total2
FROM (
SELECT b.Team, Total1 = SUM(a.total)
FROM data1 A
INNER JOIN team b ON a.teamID = b.teamID
WHERE month = 1 and year = 2019
GROUP BY Team
) d1
INNER JOIN (
SELECT b.Team, Total2 = SUM(c.total)
FROM data2 C
INNER JOIN team b ON c.teamID = b.teamID
WHERE Date BETWEEN '2019-01-01' AND '2019-01-31'
GROUP BY Team
) d2
ON d2.Team = d1.Team
WHERE d1.Total1 <> d2.Total2;
If the former, a full outer join:
SELECT Team = ISNULL(d1.Team, d2.Team), Total = ISNULL(d1.Total1, 0) - ISNULL(d2.Total2, 0)
FROM (
SELECT b.Team, Total1 = SUM(a.total)
FROM data1 A
INNER JOIN team b ON a.teamID = b.teamID
WHERE month = 1 AND year = 2019
GROUP BY Team
) d1
FULL JOIN (
SELECT b.Team, Total2 = SUM(c.total)
FROM data2 C
INNER JOIN team b ON c.teamID = b.teamID
WHERE Date BETWEEN '2019-01-01' AND '2019-01-31'
GROUP BY Team
) d2
ON d2.Team = d1.Team
WHERE ISNULL(d1.Total1, 0) <> ISNULL(d2.Total2, 0);
OTHER TIPS
WITH
cte1 AS ( SELECT b.team, SUM(a.total) total
FROM data1 a
INNER JOIN team b ON a.teamID = b.teamID
WHERE a.month = 1 and a.year = 2019
GROUP by b.team ),
cte2 AS ( SELECT b.team, SUM(c.total) total
FROM data2 c
INNER JOIN team b ON c.teamID = b.teamID
WHERE c.Date BETWEEN '2019-01-01' AND '2019-01-31'
GROUP by b.team ),
SELECT COALESCE(cte1.team, cte2.team) team,
COALESCE(cte1.total, 0) - COALESCE(cte2.total, 0) total
FROM cte1
FULL OUTER JOIN cte2 ON cte1.team = cte2.team
WHERE COALESCE(cte1.total, 0) != COALESCE(cte2.total, 0)
Of course it can be simplified - but it will decrease its clearness.
select team,total
(
select b.team,SUM(isnull(a.total,0)-isnull(c.total,0)) as Total
from team b
LEFT JOIN data1 A ON a.teamID = b.teamID and A.month = 1 and A.year = 2019
LEFT JOIN data2 C ON c.teamID = b.teamID and C.Date BETWEEN '2019-01-01' AND '2019-01-31'
group by b.team
) as t where total <>0;
Licensed under: CC-BY-SA with attribution
Not affiliated with dba.stackexchange