Reputation: 2390
I have some queries with UNION, I want to count them and show it as a row in another query
Example: I have a table called "clients", they can buy on store1, store2 or store 3, I need to show their names and how many items they bought on a row called "sales"
SELECT name,COUNT(*) FROM(
SELECT 1 FROM store1 WHERE store1.client=clients.id
UNION
SELECT 1 FROM store2 WHERE store2.client=clients.id
UNION
SELECT 1 FROM store3 WHERE store3.client=clients.id
) sales
FROM clients
If john bought 2 items from store 2 and 1 item from store 3, and mary didn't bought anything, The expected result is something like:
name | sales
------------
john | 3
mary | 0
But what I have is this error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM clients'
This is another attempt using another select subquery:
SELECT name,(
SELECT COUNT(*) FROM(
SELECT 1 FROM store1 WHERE store1.client=clients.id
UNION
SELECT 1 FROM store2 WHERE store2.client=clients.id
UNION
SELECT 1 FROM store3 WHERE store3.client=clients.id
) xxxx -- (mandatory table name)
) sales
FROM clients
This give me this error:
Unknown column 'clients.id' in 'where clause'
I hope you can help me, Thank you in advance!
Upvotes: 0
Views: 1494
Reputation: 35323
First union the tables then filter the results and counts...
You can't reference a field more than 1 level of separation. Since store1.client is 2 levels deep and clients is at level 0, you're more than 1 level of separation and this isn't allowed.
SELECT C.name, count(1)
FROM (
SELECT 'Store1' as StoreTable, a.* FROM store1 a UNION
SELECT 'Store2', b.* FROM store2 b UNION
SELECT 'Store3', c.* FROM store3 c
) S
RIGHT JOIN clients C
on C.ID = S.Client
GROUP BY Name
This makes a few assumptions
I might go one step further and just create a view called "Stores" joining all the "Stores" in a union to make other queries across stores simpler. and by hardcoding a "StoreTable name in the view you can always identify the source table if needed.
Upvotes: 2
Reputation: 2197
Almost there. Try something like:
SELECT c.name, sum(s.qt) as qt
from clients c
join (
SELECT client.id, COUNT(*) FROM(
SELECT client, sum(1) as qt FROM store1 group by client
UNION
SELECT client, sum(1) as qt FROM store2 group by client
UNION
SELECT client, sum(1) as qt FROM store3 group by client
) as sales s on (s.client = c.id)
group by c.name
I can be confusing something around MySQL and SQLServer, I'll test and let you know if there's something different.
Update: corrected the subquery, added sum and group_by and removed the where clause. It can have performance effects if you don't want to get all clients from all stores.
Upvotes: 0
Reputation: 294
SELECT name,COUNT(*)
FROM clients INNER JOIN
(
SELECT client as id, 1 FROM store1
UNION
SELECT client as id, 1 FROM store2
UNION
SELECT client as id, 1 FROM store3
)
as Stores on clients.id = Stores.id
GROUP by name
Upvotes: 2