This question already has answers here:
Inner Join Many to Many Tables with Filter In MySQL
(3 answers)
Closed 2 years ago.
I have the following tables:
product{
id
name
}
product_keyword{
prod_id
keyword_id
}
keyword{
id
keyword
}
Where a given product can have multiple keywords and a keyword can belong to multiple products.
Now I would like to, given a certain product, select all the "keyword-related" products. That is, if "prod" have keywords "key1" and "key2" I would like to select all products that have either "key1" or "key2" as keywords.
You can do this with joins:
select distinct p1.id, p1.name
from product p1
inner join product_keyword pk1 on pk1.prod_id = p1.id
inner join product_keyword pk2 on pk2.keyword_id = pk1.keyword_id
inner join product p2 on p2.id = pk2.prod_id
where p2.name = ?
The question mark represents the name of the product whose associated products you want to bring.
Related
I have 3 Tables with a n:m Relation
Languages:
ID (primary-key)
name
slug
Products:
ID
name
slug
-productgroup
Table for Relation:
Lang_Prod:
lang_prod_id (composed from lang_id and prod_id)
lang_id
prod_id
Now i want to get all Products with their corresponding Language-Names:
product
productgroup
language-names (multiple values)
I've tried:
SELECT product.*, languages_products.language_id,
GROUP_CONCAT(languages_products.language_id) as languages
FROM product
INNER JOIN languages_products ON id = languages_products.product_id
GROUP BY product.id;
Result is:
productname
product_slug
product_group
String with languages IDs
Instead of the string with the language-IDs, i would like to have a string with language-names
How can i archieve that?
You need to join with language table
SELECT product.id,product.name,product.productgroup,
GROUP_CONCAT(l.name) as languages
FROM product
INNER JOIN languages_products ON id = languages_products.product_id
INNER JOIN languages l ON languages_products.language_id=l.id
GROUP BY product.id,product.name,product.productgroup
You need to add another join with the languages table, and use the name column from it. I'd group it in an inner query though:
SELECT p.*, languages
FROM product p
JOIN (SELECT product_id, GROUP_CONCAT(l.name) as languages
FROM languages_products lp
JOIN languages l ON lp.language_id = l.id
GROUP BY product_id) cl ON cl.product_id = p.id
This question already has answers here:
SELECTING with multiple WHERE conditions on same column
(12 answers)
Closed 2 years ago.
I am working on a project where I'd like to display products that are subject to certain filters. Let's say I have the following 2 tables:
Products
id name
--------------
1 'Product 1'
2 'Product 2'
Filters
product_id filter_id
----------------------
1 a
1 b
2 a
I'm trying to write a query that only returns products if the filters are set. So if filter 'a' is active the results should be product 1 and 2, and if 'a' AND 'b' are active it should ONLY return product 1.
I've tried:
SELECT p.id
FROM products p
LEFT JOIN filters f ON f.product_id = p.id
WHERE filter.id = 'a'
GROUP BY p.id
This returns the id's for product 1 and 2 as expected. However, when I try:
SELECT p.id
FROM products p
LEFT JOIN filters f ON f.product_id = p.id
WHERE filter.id = 'a' AND filter.id = 'b'
GROUP BY p.id
I'd expect it to return the id for product 1, but it returns no results. How can I rewrite my query so that I get the product id's for the active filters? Can this be done with MySQL alone or do I have to loop through the results with php?
Your query just needs a slight change: Use OR instead of AND...change it to this:
SELECT p.id
FROM products p
LEFT JOIN filters f ON f.product_id = p.id
WHERE filter_id in ('a','b')
GROUP BY p.id
HAVING COUNT(*) = no_of_filters
This question already has answers here:
MySQL pivot row into dynamic number of columns
(1 answer)
MySQL - Rows to Columns
(13 answers)
Closed 5 years ago.
I have tree tables:
Persons:
id
name
Books
id
title
Quantity:
People_id
Product_id
quantity
I need a result with :
in the columns the Book title, in the rows the Persons name, in the cells the quantity take from the cross of peoples and books
select *
from persons p join quantity q on p.id = q.people_id
join books b on q.product_id = b.id
JOIN should help (if you need columns from all table then add alias.* for other tables in SELECT).
SELECT p.*
FROM persons p
JOIN quantity q ON p.id = q.people_id
JOIN books b ON q.product_id = b.id
I have 3 tables as follows :
Table 1: Product
id_product [Primary Key],added_time.
Table 2: Category
id_category [Primary Key],Category_name.
Table 3: product_category
id_category,id_product [Both Foreign Keys]
I want to pull Data as
Category_name,No Of Products in this Category,Last time when product was added to Category(Latest product added_time).
You could use this SQL:
SELECT Category.Category_name,
Count(DISTINCT Product.id_product) AS num_products,
Max(Product.added_time) last_added_time
FROM Category
LEFT JOIN product_category
ON product_category.id_category = Category.id_category
LEFT JOIN Product
ON Product.id_product = product_category.id_product
GROUP BY Category.Category_name;
Note that by using LEFT JOIN you will be certain to list all categories even those for which no products exist. If you don't want those, replace both LEFT keywords with INNER.
Note also that in standard SQL you need to GROUP BY any columns you mention in the SELECT list, unless they are aggregated, like with MAX or COUNT.
SELECT C.`Category_name`,
(SUM(IF(P.`id_product`IS NULL,0,1))) AS No_of_Products,
MAX(P.`added_time`) AS Latest_time
FROM
Category C
LEFT JOIN
product_category P_C ON C.`id_category` = P_C.`id_category`
LEFT JOIN
Product P ON P.`id_product` = P_C.`id_product`
GROUP BY C.`id_category`
Hope this helps.
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.