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.
Related
So I have a task all I need to do is to write Query to
select all the product names and which category they belong to.
I Using the tables from W3SCHOOL - https://www.w3schools.com/sql/trysql.asp?filename=trysql_select_all
I Would like to know why this Query -
SELECT p.ProductName
, c.CategoryName
From Products p
Join Categories c
ON p.ProductID = c.CategoryID
not working for me, it gives me only 8 Products with 8 different category names and I need all of the products name from each category.
thank you.
Your query is almost correct, you are joining on the wrong column,
SELECT Products.ProductName, Categories.CategoryName
FROM Products
JOIN Categories ON Categories.CategoryID = Products.CategoryID
should do.
The issue with your join query
You are joining Products.ProductID when you should join Products.CategoryID
The correct query should be as the following:
SELECT p.ProductName, c.CategoryName
FROM Products p
JOIN Categories c ON p.CategoryID = c.CategoryID
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 come up with two queries, both use an inner join on two different tables.
Query 1
SELECT PRODUCTS.CODE, PRODUCTS.REFERENCE, PRODUCTS.TAXCAT, PRODUCTS.DISPLAY,PRODUCTS.NAME, PRODUCTS.PRICEBUY, PRODUCTS.PRICESELL, CATEGORIES.NAME AS CATEGORY
FROM PRODUCTS INNER JOIN CATEGORIES ON PRODUCTS.CATEGORY = CATEGORIES.ID;
Query 2
SELECT PRODUCTS.CODE, PRODUCTS.REFERENCE, PRODUCTS.TAXCAT, PRODUCTS.DISPLAY,PRODUCTS.NAME, PRODUCTS.PRICEBUY, PRODUCTS.PRICESELL,STOCKCURRENT.UNITS AS UNIT FROM PRODUCTS INNER JOIN STOCKCURRENT ON STOCKCURRENT.PRODUCT = PRODUCTS.ID;
Both queries run fine on their own, when I try to use both inner joins together I get errors. This is what I came up with on my own. I'm having trouble understanding the syntax to achieve this.
SELECT PRODUCTS.CODE, PRODUCTS.REFERENCE, PRODUCTS.TAXCAT,
PRODUCTS.DISPLAY,PRODUCTS.NAME, PRODUCTS.PRICEBUY,
PRODUCTS.PRICESELL,STOCKCURRENT.UNITS AS UNIT FROM PRODUCTS INNER JOIN
STOCKCURRENT ON STOCKCURRENT.PRODUCT = PRODUCTS.ID, CATEGORIES.NAME AS
CATEGORY FROM PRODUCTS INNER JOIN CATEGORIES ON PRODUCTS.CATEGORY =
CATEGORIES.ID;
Thank you.
Your attempted query has several syntax problems. Assuming you just want to join together the three tables, you may try the following query:
SELECT
p.CODE,
p.REFERENCE,
p.TAXCAT,
p.DISPLAY,
p.NAME,
p.PRICEBUY,
p.PRICESELL,
s.UNITS AS UNIT,
c.NAME AS CATEGORY
FROM PRODUCTS p
INNER JOIN STOCKCURRENT s
ON s.PRODUCT = p.ID
INNER JOIN CATEGORIES c
ON p.CATEGORY = c.ID;
Note that I introduced table aliases here. These aliases can be used elsewhere in the query to avoid having to repeat the entire table name.
By the way, I can also see taking a union of your two original queries. But without expected output, it was not entirely clear what you want.
I have four tables that I need to pull data from. Three of the tables have a common value (product_id) the fourth table has a value in common with the third table (category_id). So they look something like this:
Products:
product_id, name, quantity, image, weight
Product_Description:
product_id, Description
Product_to_Category:
product_id, category_id
Category:
category_id, category_name
I need to pull all of the data and combine it into a result that looks like this
Name, Quantity, Image, Weight, Description, Category name
I know how to do a JOIN that works for the first three tables but I don't know how to add the into the results.
Just add an additional join on the category_id:
select p.name, p.quantity, p.image, p.weight, pd.description, c.category_name
from products p
join product_description pd on p.product_id = pd.product_id
join Product_to_Category pc on p.product_id = pc.product_id
join category c on pc.category_id = c.category_id
A Visual Explanation of SQL Joins
The code below gives me Not unique table/alias: 'presentations'
I've read several articles about this and I'm pretty sure the solution is to use aliases for my tables. I just can't understand how I create aliases or where I should add them.
Could someone please try to explain it for me?
Thanks!
SELECT categories.name, categories.sub_name, parts.name
FROM categories
INNER JOIN presentations
ON categories.id=presentations.category
INNER JOIN presentations
ON parts.id=presentations.parts
WHERE presentations.id=5;
After table name or field name you can give alias name and you can use it.
SELECT C.name, C.sub_name, PT.name
FROM categories C
INNER JOIN presentations P
ON C.id=P.category
INNER JOIN parts PT
ON PT.id=P.parts
WHERE P.id=5;
In above example C,PT,P is alias name of categories,presentation,parts table respectively.
You are joining the same table 2 times and hence you need to provide the unique alias name. However looks like you are looking for parts table and hence need to join that table
SELECT
categories.name,
categories.sub_name,
parts.name
FROM categories
INNER JOIN presentations ON categories.id=presentations.category
INNER JOIN parts ON parts.id=presentations.parts
WHERE presentations.id=5;
For better readability you can always give some short alias name something as
select
c.name,
c.sub_name,
p.name as parts_name
from categories c
join presentations pr on pr.category = c.id
join parts p on p.id = pr.parts
where pr.id = 5