Reputation: 79
I have 2 Tables A & B
A
select TranType, DocType, Document FROM
db1.dbo.A
TRANTYPE | DOCTYPE | DOCUMENT
Coup | Stat | 1
Coup | Stat | 2
Coup | Stat | 3
Coup | Stat | ...
Coup | Stat | 100
Swp | Corr | 1
Swp | Corr | 2
Swp | Corr | ...
Swp | Corr | 5
B ...
A:
SELECT TranType, DocType, COUNT (*) AS Docs
FROM db1.dbo.A
GROUP BY TranType, DocType
TRANTYPE | DOCTYPE | DOCS
Coup | Stat | 100
Swp | Corr | 5
B:
SELECT RecType, SubType, COUNT (*) AS Docs
FROM db2.dbo.B
GROUP BY RecType, SubType
RECTYPE | SUBTYPE | DOCS
Coup | Stat | 50
Cr | Cr | 3
Swp | Cr | 10
I managed to get the intersection of the 2 Tables and Add up the Count result:
A ∩ B
SELECT a.TranType, a.DocType,
(SELECT COUNT(*) FROM db2.dbo.B b WHERE b.RecType= a.TranType AND b.SubType = a.DocType) +
COUNT(a.TranType) AS SUM
FROM db1.dbo.A a
GROUP BY a.TranType, a.DocType
ORDER BY TranType
TRANTYPE | DOCTYPE | SUM
Coup | Stat | 150
Anyone got an idea how to get all the entries (Union)?
TRANTYPE | DOCTYPE | DOCS
Coup | Stat | 150 <----
Swp | Corr | 5
Cr | Cr | 3
Swp | Cr | 10
SOLUTION: I had different collation on my tables, resulting in an error.
Find the solution with proper collation handling here: SQL Sample Fiddle
Upvotes: 0
Views: 89
Reputation: 1269623
I would suggest using subqueries and then aggregating:
select TranType, DocType, sum(docs) as docs
from ((select TranType, DocType, count(*) as docs
from db1.dbo.A a
group by TranType, DocType
) union all
(select RecType, SubType, count(*) as docs
from db1.dbo.B
group by RecType, SubType
)
) ab
group by TranType, DocType;
You can also use a full outer join
, but then you have to deal with NULL
values in the final result.
Note: this will return all pairs, even those in only one table.
Upvotes: 1
Reputation: 48187
UNION
is easy. Just need matching column name
Or UNION ALL
to keep duplicated
SELECT TranType, DocType, SUM (Docs)
FROM (
SELECT TranType, DocType, COUNT (*) AS Docs
FROM TableA
GROUP BY TranType, DocType
UNION ALL
SELECT RecType as TranType, SubType as DocType, COUNT (*) AS Docs
FROM TableB
GROUP BY RecType, SubType
) T
GROUP BY TranType, DocType
ORDER BY TranType, DocType;
OUTPUT
| TranType | DocType | |
|----------|---------|-----|
| Coup | Stat | 150 |
| Cr | Cr | 3 |
| Swp | Corr | 5 |
| Swp | Cr | 10 |
EDIT
Your first query should be write like this to avoid perfom a subquery for each row.
SELECT TranType, DocType, SUM (Docs)
FROM (
SELECT TranType, DocType, COUNT (*) AS Docs
FROM TableA
GROUP BY TranType, DocType
UNION ALL
SELECT RecType as TranType, SubType as DocType, COUNT (*) AS Docs
FROM TableB
GROUP BY RecType, SubType
) T
GROUP BY TranType, DocType
HAVING COUNT(*) > 1;
Upvotes: 2
Reputation: 35780
All solutions till now just overcomplicating the problem. Also do you want counts or sums?
SELECT TranType, DocType, SUM(DOCS) DOCS--or COUNT(DOCS) DOCS
FROM (SELECT TranType, DocType, DOCS FROM A
UNION ALL
SELECT RecType, SubType, DOCS FROM B) t
GROUP BY TranType, DocType
Upvotes: 0
Reputation: 70523
Do you want a cross join?
SELECT *
FROM (
SELECT TranType, DocType, COUNT (*) AS ACount
FROM db1.dbo.A
GROUP BY TranType, DocType
) A, (
SELECT RecType, SubType, COUNT (*) AS BCount
FROM db2.dbo.B
GROUP BY RecType, SubType
) B
WHERE A.DocType = B.SubType
Upvotes: 0