unknown column in on clause error - mysql

Hey guys I am this close in being able to represent the data that I wish to display
The column in question is a.state_Id.
I understand from the research I have done that the a.State_Id is out of scope. What is the missing piece to my sql statement?
If I take out the a.State_ID = c.State_Id leaving only the b.Product_Id = c.Product_Id then the data is displayed but I need to match against the state and product.
I know i need to add in another join somewhere but im not sure how. If anyone could help me that would be awesome!
SELECT a.state_id,
a.state_name,
a.state_abbreviatedname,
b.product_id,
b.product_name,
c.stateproduct_price
FROM states a,
products b
LEFT OUTER JOIN stateproducts c
ON a.state_id = c.state_id AND b.product_id = c.product_id
Update 1
The states table has been populated and contains the following fields:
State_Id
State_Name
State_AbbreviatedName
The Products table which has been populated to contain the base products. This table has the following fields:
Product_Id
Product_Name
Each state will have the same products however the price for each product changes with each state. This is why i have the StateProducts table. This table is empty and will be populated one by one by an interface I have created. The statesproducts table will have the following fields
State_Id //reference/relational field to be user for comparison
Product_Id //reference/relational field to be user for comparison
StateProduct_Price //new field
so i understand that i will receive NULL values in the price column.
I have been able to return a sort of cartesion product of the States and products table. However I now need to append the price for each combination on the right side of this cartesion table.
bearing in mind that stateproducts table is empty how would i accomplish this?

I guess you have a Many-to-Many relationship in which States can have multiple Products and Products can be on different States. So you need to join States into the mapping table StateProducts so you can be able to get the products on table Products.
SELECT a.State_ID,
a.State_Name,
a.State_AbbreviatedName,
b.Product_Id,
b.Product_Name,
c.StateProduct_Price
FROM States a
INNER JOIN StateProducts c
ON a.State_ID = c.State_Id
INNER JOIN Products b
ON b.Product_Id = c.Product_Id
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
UPDATE 1
use CROSS JOIN keyword,
SELECT a.state_id, a.state_name, a.state_abbreviatedname, b.product_id, b.product_name, c.stateproduct_price
FROM states a
CROSS JOIN products b
LEFT OUTER JOIN stateproducts c
ON a.state_id = c.state_id AND
b.product_id = c.product_id

from A to C, C to B.
By doing LEFT JOIN for each, you'll still end up with all possible states regardless of having actual state products.
SELECT
a.State_ID,
a.State_Name,
a.State_AbbreviatedName,
b.Product_Id,
b.Product_Name,
c.Product_Price
FROM
States a
LEFT JOIN StateProducts c
ON a.State_ID = c.State_Id
LEFT JOIN Products b
ON c.Product_Id = b.Product_Id

Try writing the from clause like this:
from StateProducts c join
States a
on c.state_id = c.state_id join
Products b
on c.product_id = b.product_id
For the Cartesian product (that is, to get all examples of states and products):
SELECT s.state_id, s.state_name, s.state_abbreviatedname,
p.product_id, p.product_name,
sp.stateproduct_price
from States s cross join
Products p left outer join
StateProducts sp
on sp.state_id = s.state_id and
sp.product_id = p.product_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

Multi INNER JOIN gives unexpected duplicate records

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;

Join many to many table with others

I have a query that joins 3 tables on product id, here is the code.
SELECT oc_product.product_id, oc_product.image, oc_product.price, oc_product_description.name
FROM oc_product
JOIN oc_product_description
ON oc_product.product_id = oc_product_description.product_id;
I get the product_id, image, price and description, but I need to take the category name too, the product is in a many to many relationships with category table. Looks like this.
[oc_product_to_category * pivot table][1]
And I need to take category name from this table.
[oc_category_description][2]
[1] https://i.stack.imgur.com/5WAKd.png
[2] https://i.stack.imgur.com/YNcLn.png
Thank you so much, I am very stuck with this!
PS: I want to take category name and join with my code with other columns.
You only need to append 2 more JOINs to your query:
Join oc_product → oc_product_to_category to link products with their categories
Then Join oc_product_to_category → oc_category_description to grab the
category details
This way you can include to your query whichever fields you need from any of the joined tables.
SELECT p.product_id, p.image, p.price, d.name, c.name, c.description
FROM oc_product AS p
JOIN oc_product_description AS d
ON p.product_id = d.product_id
JOIN oc_product_to_category AS pc
ON pc.product_id = p.product_id
JOIN oc_category_description AS c
ON c.category_id = pc.category_id;
As you noted, the use of aliases for the actual table names helps to simplify a bit both the SELECT and the JOIN-ON segments of the query.
I've created a quick example here to show the results.

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

problem with the join query

SELECT *
FROM
productinfo as p ,
category as c
WHERE
c.id IN (p.category) AND
p.pid='T3'
WHERE p.category will return (1,2,3,4,5) from product info table which the id of the category.
Now i need category name used for T3 [product Id] ,but i am getting only the first category name.
Your base query is the following
SELECT * FROM productinfo as p WHERE p.pid = 'T3';
Now you need to pull in categories, per product. This is a many to one relationship, so you need a LEFT JOIN.
SELECT * FROM productinfo as p
LEFT JOIN category as c ON c.id = p.category
WHERE p.id = 'T3'
You need to learn the different types of joins and how they are used. Whenever I see someone use 'FROM table1, table2' 90% of the times it means they don't understand joins and they need a LEFT JOIN instead.
Edit based on your comment
Your datamodel is flawed. Since a product can contain multiple categories, this is really a many-to-many relationship. You should create a product_category table that connects product id's with category id's.