I'm trying to create a database that is structured so that I can do ONE query and get all the data I need.
this is how I have it structured now:
Products Subcategory Category
------------- ------------- -------------
| id | name | | id | name | | id | name |
It makes sense to me to create two relational tables that ties the product to the subcategory, and the subcategory to the category (making it hierarchical):
prod_sub_relation sub_cat_relation
---------------------------- ---------------------------
| id | prod_id | subcat_id | | id | subcat_id | cat_id |
So the product can be in MULTIPLE subcategories, and the subcategory tells us what category the product is in.
With this structure, if I wanted to find all the products with a category_id, I'd have to query the sub_cat_relation table, then take that array and make another query for the prod_sub_relation table (and that's just messy).
My goal is to find all products, or all categories, or all subcategories with ONE id (whether it's product_id, category_id, or subcategory_id)
Is this possible? or am I doing something wrong here?
As already mentioned by #har07 you could use a simple JOIN on this one.
I am not exactly sure the other details of the structure of your tables but
I will show you based on what you have provided so far:
SELECT p.ID, p.Name, c.Name as CategoryName, s.Name as SubCategoryName
FROM Products P
INNER JOIN SubCategory S
ON P.subcat_id = S.subcat_id
INNER JOIN Category C
ON S.cat_id = C.cat_id
You could then use a WHERE clause to specify which product you want to display along with its category and subcategory
SELECT P.ID, P.Name, C.Name as CategoryName, S.Name as SubCategoryName
FROM Products P
INNER JOIN SubCategory S
ON P.subcat_id = S.subcat_id
INNER JOIN Category C
ON S.cat_id = C.cat_id
WHERE P.ID = valuehereforyourID
To get the Products and SubCategory for a given category ID you just change the WHERE clause, like:
WHERE C.cat_id = ValueForCategoryIDhere
To get the Products and Category for a given Subcategory ID you just change the WHERE clause, like:
WHERE S.subcat_id = ValueForSubCategoryIDhere
Put each products' categories in an array, serialize the array, and store that in the DB...
Related
I have 3 models, Store, Item and Brand. I want to figure out in which stores a given brands items can be found.
I've been trying to create a SQL statement to achieve this, but I can't get near the right result.
Essentially, I want to give the brand ID 1, and get a list of stores that have products from this brand.
How can I do this?
Here's my 4 tables:
brand
id | name
items
id | name | brand_id
stores
id | name
stores_items
id | store_id | item_id
You just need to JOIN your tables. This will return all stores where you can find brand = 1:
SELECT DISTINCT stores.name
FROM
stores INNER JOIN stores_items
ON stores.id = stores_items.store_id
INNER JOIN items
ON stores_items.item_id = items.id
WHERE
items.brand_id = 1
I know title is a bit confusing but i dont know how to name it better.
I have tables like that:
products:
product_id | product_name | product_category1 | product_category2
categories
category_id | category_name
I want to select record which looks like that:
product_id | product_name | category_name | subcategory_name (where category is category1 and subcategory is category2)
So what i need is to join 2 columns where each column is the "category_name" column but category_name has to have id saved in product_category1 and subcategory_name has to have id saved in product_category2
I tried a lot of things, but i am really stuck. I cant even paste my concept because, currently, i dont have one.
You just need to join products and categories twice, using different aliases for the categories table in the two joins. Something like:
SELECT prd.product_id, prd.product_name,cat.category_name,subcat.category_name
FROM products AS prd
JOIN categories AS cat ON cat.category_id = prd.product_category1
JOIN categories AS subcat ON subcat.category_id = prd.product_category2
Let's say that I have the following tables in my MySQL database:
TABLE Products
| id | some_column1 | some_column2 |
TABLE ProductProperties
| id | product_id | name |
Oversimplified, but sufficient. Now I want to get all products with properties. I do:
SELECT * FROM `Products` JOIN `ProductProperties` ON Products.id = ProductProperties.product_id
What do I get?
| id | some_column1 | some_column2 | id | product_id | name |
It's not cool, and I want to make it cool in one of the two ways:
1) To get the array of objects like in Product table, but extended by one more member, which would be the array of properties which matched JOIN. I've sort of figured out already that it's impossible?
2) To get the array like this (I'd still have to iterate over it in PHP to join all properties in one product into one object):
| product_id | some_column1 | some_column2 | property_id | product_id | name |
So I'd like to rename the column ProductProperties.id into ProductProperties.property_id. If I could remove ProductProperties.product_id from the output too, that would be ideal, but for now, I only want the way to rename one column in the output. Or to prefix it by table name. Or something like that.
Doable?
You should explicitly name the columns and not use *. Then, don't return redundant columns:
SELECT p.id as productid, p.some_column1, p.some_column2,
pp.id as ProductPropertiesId, pp.name
FROM `Products` p JOIN `ProductProperties` pp
ON p.id = pp.product_id
Also, table aliases make such a query more readable.
SELECT Products.id product_id,
Products.some_column1,
Products.some_column2,
ProductProperties.id property_id,
ProductProperties.name
FROM `Products`
JOIN `ProductProperties`
ON Products.id = ProductProperties.product_id
I would like to run a query on two table "products" and "category", There are 30 record in my product table. product table has a column name category_ids varchar(255),which storing the ids of category in the format like(10,11,12,130,..) for each record of products table. In sort a product can be many categories. category table having a column name parent_id which is the parent category of that category.
I want to list the record with all category of that product.
For example look at one record of the products table having id = 7.
product_Id = 7,
category_ids = '213,215,216',
product_name = 'Ponds',
.....
Means product ponds has three category = category.id = 213, category.id = 215 and category.id = 216.
I want to list here all three records of ponds like in this format :=
product_Id | product_name | category_name | parent_category_name
7 ponds cream chemical
7 ponds medicine chemical
7 ponds powder Ayurvedic
I am trying with this query :-
select
p.id as product_id,
p.product_name,
child.name as category_name,
parent.name as parent_category_name
from category child
left join products p on child.id in(p.category_ids)
left join category parent on parent.id = child.parentid and parent.parentid = 0
where p.id = 7
The above query getting only one record not all three records as above.
What condition and joining in this query will be applied to get result as above described.
Sorry for spending your valuable time.
Any suggestions and ideas would be greatly appreciated.
Thanks a lot.
Try to change ON condition -
LEFT JOIN products p ON child.id IN(p.category_ids)
->
LEFT JOIN products p ON FIND_IN_SET(child.id, p.category_ids)
...because:
SELECT 1 IN ('1,2,3') find_1, 2 IN ('1,2,3') find_2;
+--------+--------+
| find_1 | find_2 |
+--------+--------+
| 1 | 0 | -- 0 !
+--------+--------+
SELECT FIND_IN_SET(1, '1,2,3') find_1, FIND_IN_SET(2, '1,2,3') find_2;
+--------+--------+
| find_1 | find_2 |
+--------+--------+
| 1 | 2 |
+--------+--------+
GROUP_CONCAT function.
example:
SELECT p.product_Id, p.product_name, GROUP_CONCAT(c.category) FROM products p
JOIN category c
ON FIND_IN_SET(child.id, p.product_Id)
GROUP BY p.product_Id;
I don't understand MySQL very well, here are the table structures I am using.
users
id | first_name | last_name | username
| password
categories
id | user_id | name | description
links
id | user_id | category_id | name |
url | description | date_added |
hit_counter
I am trying to return a result set like this, to give information about the category for a user that includes how many links are in it.
id | user_id | name | description | link_count
At the moment I have this query, but it only returns rows for categories that have links. It should return rows for categories that do not have any links (empty categories).
SELECT categories.*, COUNT(links.id)
FROM categories LEFT JOIN links ON
categories.id=links.category_id;
How to do this query? Thanks.
we can't do select table dot "star" with an aggregate.
what you wanna do is something like (pseudocode):
select
categories.field1,
categories.field2,
{etc.}
count(links.id)
from categories
left join links
on categories.id = links.category_id
group by
categories.field1,
categories.field2,
{etc.}
iow: you're missing the group by code-block to get the right aggregate in your query result set.
To mold alien052002's answer to fit your specific question, the following (untested) should work:
select c.id,
c.user_id,
c.name,
c.description,
count(l.link_count)
from categories c
left join links l on l.category_id = c.id
group by c.id, c.user_id, c.name, c.description
try this
SELECT categories.*, COUNT(links.id) FROM categories LEFT JOIN links ON categories.id=links.category_id group by categories.id;