I have three tables in MySQL.
customers which has columns {id, name, and email}
products which has columns {id and name}
purchased which contains {id, customer}
product where customer and product are indexes of customers.id and products.id respectively.
I am a little confused on how to get the customer's name and all products he has purchased. Here is what I have and it is basically returning all possible combinations of products and customers instead of the specific customers info:
SELECT
customers.email,
products.name
FROM
customers, products, purchased
INNER JOIN
customers cu
ON
cu.id = purchased.customer
INNER JOIN
products pr
ON
pr.id = purchased.product
WHERE
purchased.customer = 1
I expect this to return all products purchased by a customer with ID of 1 but it is not. Can someone help me here?
You are mixing the explicit and implicit join and hence creating the issue.
You may have the query as below. In addition you have used alias for the joining tables and need to use them in the select as well.
SELECT cu.email, pr.name FROM purchased
INNER JOIN customers cu
ON cu.id = purchased.customer
INNER JOIN products pr
ON pr.id = purchased.product
WHERE pr.customer = 1
Related
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
Running the following SELECT query gives unexpectedly two times the same record while there is only 1 product in the database. The are however multiple subcategories linked to the same category, but I still don't understand why this would give two results.
The ERD:
The full contents of the DB:
SELECT p.id AS productId, p.name AS productName FROM product p
INNER JOIN product_base AS pb ON pb.id = p.product_base_id
INNER JOIN product_category AS pc ON pc.id = pb.product_category_id
INNER JOIN product_subcategory AS psc ON psc.product_category_id = pc.id;
Returns:
Why is this product returned two times?
Appending WHERE psc.id = 2 will still give one product as a result, while the intention is that this product should only be found when psc.id = 1.
What am I missing here? Is there something wrong with the structure? How would I get all products that have a certain subcategory?
Would I need to store product_category_id and product_subcategory_id directly in product as well?
#barmar made me realize I am simply missing a direct FK from product to product_subcategory. Otherwise there is of course a missing link between the product and subcategory.
DISTINCT will filter out the duplicates.
SELECT DISTINCT p.id AS productId, p.name AS productName
FROM product p
INNER JOIN product_base AS pb ON pb.id = p.product_base_id
INNER JOIN product_category AS pc ON pc.id = pb.product_category_id
INNER JOIN product_subcategory AS psc ON psc.product_category_id = pc.id;
I have these tables:
Customer = {id,firstname,last name,street,city}
Invoice = {id, customerid, total}
Item = {invoiceid, item, productid, quantity, cost}
Product = {id, name, price}
I would like to get the first name of the customer and the list of products what he bought.
I have created an sql code:
select customer.firstname, product.name from product
inner join item on item.productid = product.id
inner join invoice on invoice.id=item.invoiceid
inner join customer on customer.id=invoice.customerid
where customer.id=24
the customer.id is 24, because on this id I should get only 3 items' name.
Unfortunately, I am getting multiplication of these items.
What should I repair in my query?
I am getting multiplication of these items.
That is how relational databases work when you ask for a join. You get a Cartesian Product of the matching records.
However, MySQL has a facility that lets you put multiple values into a single field - it's called group_concat:
SELECT
customer.firstname
, GROUP_CONCAT(product.name SEPARATOR ', ')
FROM product
INNER JOIN item ON item.productid = product.id
INNER JOIN invoice ON invoice.id=item.invoiceid
INNER JOIN customer ON customer.id=invoice.customerid
WHERE customer.id=24
GROUP BY customer.id
Note the use of GROUP BY, which "merges" all rows for the same customer id into a single group, on which GROUP_CONCAT operates.
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.
I'm trying understand how I can pull information from multiple tables at once in one query if that is possible.
I have 3 tables and I'm wondering if there is a way I can query all the product names for customers that live in california?
Table:
products
Fields:
productOid
productName
companyOid
Table:
customerData
Fields:
customerOid
firstName
lastName
state
Table:
orders
Fields:
orderNumber
customerOid
productOid
Would this fall under something like an INNER JOIN?
Also, I'm learning mySQL.
You will need to use inner joins for this.
SELECT DISTINCT p.productName
FROM orders o
INNER JOIN customerData c ON o.customerOid = c.customerOid
INNER JOIN products p ON o.productOid = p.productOid
WHERE c.state = 'CA';
I am using DISTINCT here because it's possible a customer would order the same product more than once (or multiple customers would order the same products) and I'm assuming you don't want duplicates.
I'm also making the assumption that your state is represented as a two character column.
Read more about joins
You could use one more join, but I would write it this way:
SELECT DISTINCT p.productName
FROM
orders o INNER JOIN products p
ON o.productOid = p.productOid
WHERE
o.customerOid IN (SELECT customerOid
FROM customerData
WHERE state = 'California')
It might be a little slover than a join, but it's more readable.
This shows products that CA customers have ordered:
SELECT p.productName
FROM orders o
INNER JOIN products p ON o.productOid = p.productOid
INNER JOIN customerData c ON o.customerOid = c.customerOid
WHERE c.state = 'CA'