Inner Join on many-to-many relationship on the same table - mysql

I came across a weird problem while I was trying to apply the Inner Join on the table which has 3 columns -
Table category_subcategory_relation
id (PK)
category_id_ref (FK)
subcategory_id_ref (FK)
The columns category_id_ref and subcategory_id_ref are the primary keys of the table category.
Table category
id (PK)
category_name (Varchar(200))
I want to Inner Join this two tables and get the columns as following -
Category_Name
Subcategory_Name
I am not able understand how would I be able to get the category_name column from the category table twice, once for the column Category_Name (FK) and again for the column Child_Category_Name (FK).

You would have to perform two joins, one each on category_id_ref and subcategory_id_ref:
SELECT a.*,
b.category_name AS Category_Name,
c.category_name AS Subcategory_Name
FROM category_subcategory_relation a
JOIN category b
ON a.category_id_ref = b.id
JOIN category c
ON a.subcategory_id_ref = c.id
While your category table contains category and subcategory information, you'll have to look at them as two separate tables (one for category and other for subcategory) to bring this information back to your category_subcategory_relation table.

Related

How to get Data from three tables in one query where table 2 contains foreign keys from table 1 and 3

I want to get all the suppliers for one product with product details for which I am using following tables.
I have one Table products with columns
id(pk)
name
type
second table product_supplier with columns
psid(pk)
pid(fk from products)
sid(fk from supplier)
third table supplier with columns
id(pk)
firstname
lastname
I want to get data from these three tables in one mysql query.
Is this what you are looking for?
select p.*, s.*
from products p
inner join product_supplier ps on ps.pid = p.id
inner join supplier s on s.id = ps.sid
order by p.id, s.id
This will return each product along with all the associated suppliers.

Database model correction mysql?

I have created a database of 3 tables: "products", "brands" and "categories".
products table has product_id, brand_id, category_id, etc. So by using category_id and brand_id from other tables, I can pick up and show the different data from product table.
However, I want a solution like, for example, what if a product lies in two or more categories? What should be the database model and what table changes should I need to do more in my database?
My table structures are listed below:
Database:
Brand table:
Category table:
Product table:
Mapping cardinalities between product and category table are many to many. So you have to create a new table to keep records product and category relationship according to database normalization. SO remove category_id from the product table and create a table like as the below. For example
create table productCategory(
product_id integer references product_table(product_id),
category_id interger references category_table(category_id),
primary key (product_id,category_id)
);
there is two solution from my logic:
Change type of cat_id column in product table, using VARCHAR or TEXT, so each product have cat_id with separated by comma or colon, example value: 1,4,5
Remove column cat_id from product table, Add another table for mapping product into cat_id, example scheme:
CREATE TABLE product_mapping (
id INT(11) NOT NULL AUTO_INCREMENT,
product_id INT(11) NOT NULL,
cat_id INT(11) NOT NULL,
PRIMARY KEY (id)
)
So.. you can query by joining 3 table for product information, with example query as below:
SELECT pm.cat_id AS m_cat_id, pm.product_id AS m_product_id, p.*, c.*
FROM product_mapping AS pm
INNER JOIN products AS p ON p.id = pm.product_id
LEFT JOIN categories AS c ON c.cat_id = pm.cat_id
WHERE pm.product_id = :produc_id

Reading a database diagram

I've been trying to figure out how to get the products that match a certain category id but I have been unable to figure out how to move from category to products.
How would a query that basically selects all products that match a certain category id look?
This should work:
SELECT products.*
FROM products,
product_category
WHERE product_category.categoryid = CATEGORY_ID
AND products.catalogid = product_category.catalogid
Or if you prefer a join:
SELECT products.*
FROM products
INNER JOIN product_category ON products.catalogid = product_category.catalogid
WHERE product_category.categoryid = CATEGORY_ID
Simply replace CATEGORY_ID by the ID of the category you wish to select.
product_category is a link table, joining the tables products and product_category together: it contains the catalogid, referencing the ID of the category, and catalogid, referencing the ID of the product.

How to associate sub-category to a field in database?

I am creating a MySQL database. I have a column named, name of the product. The product has one Main Category. However, it can belong to n-number of sub categories. I need to map these sub categories to that product. How can I do that?
Table1 - Product Info
Columns - ID, Name, MainCategory, SubCategory (Not Sure Exactly)
Table2 - MainCategory
Columns - ID, Name
Table3 - SubCategory
Columns - ID, Name
Table1 has 1-to-1 relationship to Table2.
How do I map Table1 to Table3? Am I doing this wrong?
Thought: I want to do it in the manner so that whenever I click on any subcategory name on a website, I get a list of all the products under that category. Just like it happens in Online Stores Website.
Example: The product External Hard Drive will come under Computer Accessories. But I want to give it sub-categories like offer_running, 500GB, SomeCompanyName, black etc.
Hope I explained my question. Please help me in the designing of database. I have got all the basics of DBMS, but I don't know how to involve keywords and to store & map them in a database.
How about the following structure:
Table1 - Product Info
Columns - ID, Name, Main_Category_ID
Table2 - Category
Columns - ID, Name
Table3 - Product_Category
Columns - ID, Product_ID, Category_ID, Name
Then you could use the following query to get all of the get all of the information:
SELECT p.*, c.Name
FROM [Product Info] p
INNER JOIN Product_Category pc ON p.ID = pc.Product_ID
INNER JOIN Category c ON pc.Category_ID = c.ID
Notice that in the Product Info table I added a Main_Category_ID field. If you really need to identify the main category then this would work:
SELECT p.ID, p.Name, NULL AS MainCat, c.Name AS SubCat
FROM [Product Info] p
INNER JOIN Product_Category pc ON p.ID = pc.Product_ID
INNER JOIN Category c ON pc.Category_ID = c.ID
UNION
SELECT p.ID, p.Name, c.Name AS MainCat, NULL AS SubCat
FROM [Product Info] p
INNER JOIN Category c ON p.Main_Category_ID = c.ID
First of all, if table 1 and table 2 have a 1-1 relationship, there is no need for having two separate tables. This will make query processing faster and will eliminate the need for an extra join.
Can you clarify what the ID column in table 3 refers to? Is this an unique ID for table 3 or the ID from table 1?
If former is the case, then you need to have the ID column of table 1 as the foreign key in table 3. That will resolve your issues.
Hope that helps.

How to join to a one to many relationship table?

I have three tables, lets say for example table 1 is locations, then table 2 is location_items then table 3 is items
location_items is the link between locations and items
each locations has one location_items and each location_items has either one or more items
Column names:
locations table: location_id primary key
location_items table: location_items_id primary key, location_id foreign key, item_id foreign key(one is to many, 1 location, many items).
items table: item_id primary_key, name(name of the item that i want to get)
Now what I want is select the locations, then join to location_items, then join to items to get the lets say the first items.name that is not null. Here is my sample query:
SELECT l.location_id,COALESCE(i.name)
FROM locations l
LEFT JOIN location_items li USING(location_id)
LEFT JOIN items i USING(item_id)
WHERE l.location_id LIKE '%P021%'
GROUP BY l.location_id
But I only get all the location_ids with null name