SQL Many to many to many - mysql

I'm having an issue with a query I have to build. There are 3 tables,all many to many after one another.
Table Stores - id,store_name
Table Clients - id,store_id,client_name
Table Products - id,client_id,product_name
In a few words - One Product can be bought from many Clients. And one Client can be in many Stores.
The task is to get all Stores with the number of their Clients (a person is a client who bought at least one product. If that client_id does not bought at least 1 Product - he is not a real Client).

SELECT store_name, COUNT(store_name)
FROM Stores s
INNER JOIN Clients c on (s.id = c.store_id )
INNER JOIN Products p on (c.id = p.client_id)
GROUP BY store_name

get a count of clients and then do a left join among the tables like below
select s.store_name,
t.client_count
from stores s left join
(
select c.store_id, count(p.id) as client_count
from Clients c left join products p
on c.id = p.client_id
group by p.client_id
) t on s.id = t.store_id

Related

How to handle multiple JOIN and LEFT JOINS in MySQL

I have 5 tables that need to be joined. These tables have to do with orders placed by customers and the orders turned into purchase orders for the relevant suppliers.
Table product_sale holds the customers products that they've ordered.
Table product holds the main information on those products.
Table sale_purchase is a bridging table between the sale and purchase order.
Note: This may or may not exist as the product might be out of stock and no purchase order was required.
Table product_purchase holds those linked products on the purchase order.
Table grn handles the receiving of those products.
Unfortunately in the customers sales order, I will need to access information from all of these tables. Here's the query I have so far:
SELECT
ps.*,
pp.received_qty,
p.group_ref,
p.subgroup_ref,
g.grn_id AS 'grn_ref',
g.grn_date
FROM
product_sale ps
INNER JOIN product p ON ps.product_ref = p.product_id
LEFT JOIN sale_purchase sp ON ps.sale_ref = sp.sale_ref
LEFT JOIN product_purchase pp ON pp.so_line_no = ps.line_no
LEFT JOIN grn g ON g.grn_id = pp.grn_ref
WHERE
ps.sale_ref = 150002
GROUP BY
line_no
ORDER BY
line_no
So far so good, although the received_qty for one line is wrong:
The first line's received qty should be 7 and not 4. I've checked the grn table and it definitely says 7. Can I please get some help as to where I am going wrong with this query? Also the grn_ref and grn_date should be NULL for line_no 1.00
Scrap it guys. I figured it out. I hadn't accounted for another purchase order that was in the system. Solution to the problem was adding AND pp.purchase_ref = sp.purchase_ref to the left join for product_purchase. See revised code below:
SELECT
ps.*,
pp.received_qty,
p.group_ref,
p.subgroup_ref,
g.grn_id AS 'grn_ref',
g.grn_date
FROM
product_sale ps
INNER JOIN product p ON ps.product_ref = p.product_id
LEFT JOIN sale_purchase sp ON ps.sale_ref = sp.sale_ref
LEFT JOIN product_purchase pp ON pp.so_line_no = ps.line_no AND pp.purchase_ref = sp.purchase_ref
LEFT JOIN grn g ON g.grn_id = pp.grn_ref
WHERE
ps.sale_ref = 150002
GROUP BY
line_no
ORDER BY
line_no

mysql joins with many to many relationship

I am trying to learn joins with many to many relationships in mysql,
I have four tables:
customers, orders, products, payments
I am trying to get records as:
customer_name, order_status, pay_method, pro_name
the query I use:
SELECT cust_name,order_status,pay_method,pro_name FROM customer
INNER JOIN orders ON customer.cust_id = orders.cust_id
INNER JOIN payments ON payments.order_id = orders.order_id
INNER JOIN products ON products.pro_id = orders.pro_id
I am receiving results as I want with no issue. But this query shows only one product against one order, then I realize I should have another separate table which will hold many products against one order. In this issue I am not able to get desired result
It's not entirely clear what you're asking, but I'm guessing what you're trying to do is create a many to many table that links orders and products? In which case, you can just create a table called "productorders" which will contain an order_id and a pro_id. Then you would modify your query like this:
SELECT cust_name,order_status,pay_method,pro_name FROM customer
INNER JOIN orders ON customer.cust_id = orders.cust_id
INNER JOIN payments ON payments.order_id = orders.order_id
INNER JOIN productorders ON productorders.order_id = orders.order_id
INNER JOIN products ON products.pro_id = productorders.pro_id;
Joining productorders will get all products associated with an order, and then joining products will get the information associated with each product.

COUNT via multi-chain join

I have this hierarchy in my database (from lowest to highest):
User => Dept => Area => Company
Now I need to make a table that shows all companies (some info about them taken directly from companies table) but the last column in the HTML table I want to be Number of users. I know I need to join the tables together and perhaps join table to itself, but how do I do this?
Each of these tables have a column linking to its parent table (except Company ofc).
JOIN the tables:
SELECT
c.companyId,
c.CompanyName,
IFNULL(COUNT(u.userID), 0) AS 'Number Of Users'
FROM Company AS c
LEFT JOIN Area AS a ON c.CompanyID = a.CompanyID
LEFT JOIN Dept AS d ON a.DeptId = d.DeptId
LEFT JOIN users AS u ON D.UserId = u.UserId
GROUP BY c.companyId,
c.CompanyName;
Note that: LEFT JOIN with IFNULL will give you those companies that has no matched rows in the other tables; with count zero in this case

MYSQL issue - join not enough

i have 3 tables: products, buyers and ratings.
a buyer can rate i product and this will be saved as a row in ratings (with buyer_id and product_id) and a buyer can mark one product (at most one favorite product per buyer) as favorite (a binary flag in ratings).
i have a report of all buyers and want to add to each row in the report the name of the buyer's favorite product (if he has one), i tried this:
SELECT b.*, p.name
FROM buyers b, products p
LEFT JOIN ratings r
ON r.buyer_id = b.id
and r.product_id = p.id
and r.isFav=1
unfortunately this throws an error (Unknown column 'b.id' in 'on clause'). so i feel that i'm going the wrong way about it.
is there something that can help me accomplish what i need?
Without seeing the any data, one of the big problems is you are mixing JOIN syntax, I might rewrite it this way:
SELECT b.*, p.name
FROM buyers b
LEFT JOIN ratings r
ON b.id = r.buyer_id
LEFT JOIN products p
ON r.product_id = p.id
WHERE r.isFav=1

Retrieve Clients from Projects User Belongs to

Users can have multiple projects and projects can have multiple clients.
How do I get all the unique clients from the projects a user belongs to?
Tables:
- Users
- Projects
- Clients
- Project Clients
SELECT client_id, client_name FROM clients.. ? JOINS, USING.. ?.. what?
Firstly, if users can have multiple projects, you'll need a Project-Users table.
Given that, you can get what you want using either of these pieces of SQL:
select distinct c.id from
clients c
join projectclients pc on c.id=pc.clientid
join projects p on pc.projectid=p.id
join projectusers pu on p.id=pu.projectid
join users u on u.id=pu.userid
where u.id=3
select distinct c.id from
clients c join projectclients pc on c.id=pc.clientid
where pc.projectid in
(select projectid from
users u join projectusers pu on u.id=pu.userid
where u.id=3)