Complex multiple join query across 3 tables
- by Keir Simmons
I have 3 tables:
shops, PRIMARY KEY cid,zbid
shop_items, PRIMARY KEY id
shop_inventory, PRIMARY KEY id
shops a is related to shop_items b by the following: a.cid=b.cid AND a.zbid=b.szbid
shops is not directly related to shop_inventory
shop_items b is related to shop_inventory c by the following: b.cid=c.cid AND b.id=c.iid
Now, I would like to run a query which returns a.* (all columns from shops). That would be:
SELECT a.* FROM shops a WHERE a.cid=1 AND a.zbid!=0
Note that the WHERE clause is necessary.
Next, I want to return the number of items in each shop:
SELECT a.*, COUNT(b.id) items FROM shops a
LEFT JOIN shop_items b ON b.cid=a.cid AND b.szbid=a.zbid
WHERE a.cid=1 GROUP BY b.szbid,b.cid
As you can see, I have added a GROUP BY clause for this to work.
Next, I want to return the average price of each item in the shop. This isn't too hard:
SELECT a.*, COUNT(b.id) items, AVG(COALESCE(b.price,0)) average_price FROM shops a
LEFT JOIN shop_items b ON b.cid=a.cid AND b.szbid=a.zbid
WHERE a.cid=1 GROUP BY b.szbid,b.cid
My next criteria is where it gets complicated. I also want to return the unique buyers for each shop. This can be done by querying shop_inventory c, getting the COUNT(DISTINCT c.zbid). Now remember how these tables are related; this should only be done for the rows in c which relate to an item in b which is owned by the respective shop, a.
I tried doing the following:
SELECT a.*, COUNT(b.id) items, AVG(COALESCE(b.price,0)) average_price, COUNT(DISTINCT c.zbid) FROM shops a
LEFT JOIN shop_items b ON b.cid=a.cid AND b.szbid=a.zbid
LEFT JOIN shop_inventory c ON c.cid=b.cid AND c.iid=b.id
WHERE a.cid=1 GROUP BY b.szbid,b.cid
However, this did not work as it messed up the items value. What is the proper way to achieve this result?
I also want to be able to return the total number of purchases made in each shop. This would be done by looking at shop_inventory c and adding up the c.quantity value for each shop. How would I add that in as well?