Reputation: 5891
I have a problem trying to select the total from multiple tables using joins. The results of COUNT
are not correct.
I have three tables:
Customers
id -> Primary/Autoincrement
name
Documents
id -> Primary/Autoincrement
customer_id
Documents_items
id -> Primary/Autoincrement
document_id
And I would like to obtain the total, grouped by customer name, of documents and documents items.
SELECT cust.name,
COUNT(doc.id),
COUNT(item.id)
FROM customers AS cust
INNER JOIN documents AS doc ON doc.customer_id = cust.id
INNER JOIN documents_items AS item ON item.document_id = doc.id
GROUP BY cust.name
The problem is that the result of COUNT(doc.id)
is equal to the result of COUNT(item.id)
which is not correct.
You can see a demo example of the error in SQLFiddle.
Input example:
INSERT INTO customers VALUES('John')
INSERT INTO documents VALUES(1)
INSERT INTO documents_items VALUES(1), VALUES(1)
Output expected:
Name | Total Docs | Total Items
John 1 2
Current output:
Name | Total Docs | Total Items
John 2 2
Upvotes: 3
Views: 59
Reputation: 16553
You want to count the distinct document id's and item id's.
SELECT cust.name,
COUNT(DISTINCT doc.id),
COUNT(DISTINCT item.id)
FROM customers AS cust
INNER JOIN documents AS doc ON doc.customer_id = cust.id
INNER JOIN documents_items AS item ON item.document_id = doc.id
GROUP BY cust.name
Upvotes: 6
Reputation: 18737
Try this way:
SELECT T1.name,T1.Docs,T2.Items
FROM
( SELECT cust.name, COUNT(doc.id) as Docs
FROM customers AS cust
INNER JOIN documents AS doc ON doc.customer_id = cust.id
GROUP BY cust.name) T1 JOIN
( SELECT cust.name, COUNT(item.id) as Items
FROM customers AS cust
INNER JOIN documents AS doc ON doc.customer_id = cust.id
INNER JOIN documents_items AS item ON item.document_id = doc.id
GROUP BY cust.name) ON T1.name =T2.name
Explanation:
You have to generate two result with each count. And then join those result with name field.
First inner query will generate the name and count of docs. Second inner query will generate the name and count of items. Then we will join those queries on the name field.
Upvotes: 0