I searched lots of similar topics about this but can't find the answer to this specific probem.
So I have a table with categories and I have another table with products, so what I want is select all the categories that contain at least 1 product, seems very easy but the following code dont give me what I expect.
SELECT *
FROM categories
INNER JOIN products on (categories.id = products.cat_id)
HAVING count(products.cat_id) > 0
All help is appreciated.
Thank you!
You can actually get what you want with just a join because any categories without products will not match.
You should also add a DISTINCT or GROUP BY to remove the duplicate category records from the results:
SELECT DISTINCT c.*
FROM categories c
JOIN products p
ON c.id = p.cat_id
OR:
SELECT c.*
FROM categories c
JOIN products p
ON c.id = p.cat_id
GROUP BY c.id
If you want something fancy like categories that have 2 or more products then you can use GROUP BY and HAVING:
SELECT c.*
FROM categories c
JOIN products p
ON c.id = p.cat_id
GROUP BY c.id
HAVING count(*) >= 2
Try this select in this select all categories that have at least one product
select categories.* from categories
left join products on (categories.id = products.cat_id)
where products.cat_id IS NOT NULL
group by categories.id
In this case you're not using "HAVING" but will have the same result
Related
for this i have 3 tables
categories(id,category)
products(id,category_id,name)
productstock(id,product_id,quantity)
the query written for this
select categories.category,sum(productstock.quantity)
from categories
inner join productStock on products.id=productstock.product_id
inner join products on categories.id=products.category_id
group by category;
it would be a great help
Try using LEFT JOIN.
SELECT c.category, SUM(quantity) AS 'sum_qty' FROM productstock a
LEFT JOIN products b ON a.product_id=b.id
LEFT JOIN categories c ON b.category_id=c.id
GROUP BY category_id;
I have problem with join left. It work fine but i don't see null results. It connects three tables - categories, product_categories and order_products.
Query made by stack user look's like:
SELECT
categories.name,categories.id,
SUM((orders_products.product_price_gross + orders_products.option_price)*(1 - (orders_products.rebate/100)) * orders_products.product_qty) as suma
FROM orders_products
LEFT JOIN product_categories
ON product_categories.product_id = orders_products.product_id
LEFT JOIN categories
ON product_categories.category_id = categories.id
GROUP BY categories.name, categories.id
ORDER BY suma DESC
I'm not sure how upgrade this query - I need to see what never been sold to show on shop statistics.
I hope You could help me.
Kind regards
Mark
You want to see products that has not been sold? Your main table is the transaction table orders_products. So any product not "ordered" will not show. Interchange product_categories and orders_products to achieve what you want. This will list all categories and null out the "suma" if JOIN statement cannot find the product_id listed in the "order_products" table
SELECT
categories.name,
categories.id,
SUM((orders_products.product_price_gross + orders_products.option_price)*(1 - (orders_products.rebate/100)) * orders_products.product_qty) AS suma
FROM product_categories
LEFT JOIN orders_products
ON product_categories.product_id = orders_products.product_id
LEFT JOIN categories
ON product_categories.category_id = categories.id
GROUP BY categories.name, categories.id
ORDER BY suma DESC
I have got 2 tables: categories and products.
Categories have parent-child relationship structure and the data is fetched by joining the same table.
When fetching the data, I have to count:
how many products each category contains which have stock >= 1
how many subcategories a category contains which contain at least 1 product with stock >= 1
SELECT c. * , count( DISTINCT s.cat_id ) AS number_of_subcategories, count( DISTINCT p.id ) AS number_of_products FROM categories c
LEFT JOIN categories s
ON s.parent_id = c.cat_id
LEFT JOIN products p
ON p.cat_id = c.cat_id AND p.stock >= 1
GROUP BY c.cat_name
ORDER BY number_of_products ASC
At the first glance all goes well, but unfortunately I get total number of all subcategories.
Do I miss one more join or what is my problem so far?
Here is the code: SQLFiddle
You could alter your query to use a subquery to get the number of subcategories similar to this:
SELECT c.cat_id,
c.parent_id,
c.cat_name,
count(sp.cat_id) AS number_of_subcategories,
count(DISTINCT p.id) AS number_of_products
FROM `categories` c
LEFT JOIN
(
select distinct s.cat_id, s.parent_id
from categories s
inner join products p
on s.cat_id = p.cat_id
where p.stock > 1
) sp
ON sp.parent_id = c.cat_id
LEFT JOIN products p
ON p.cat_id = c.cat_id
AND p.stock >= 1
GROUP BY c.cat_id, c.parent_id, c.cat_name;
See SQL Fiddle with Demo
Try changing AND for WHERE. Does it work?
Francisco
I'm trying to display a list of items with their name and all categories they belong to.
My database structure is:
Items table with Id, Item_Name.
Categories table with Id, Category_Name
Items_Categories table with Id, Item_id, Category_id.
I'd like to display the results in a table with the Item Name, and a comma-delimited list of its Categories' Names. I'm not sure how to do this with a single query. Thanks in advance.
You need to use the GROUP_CONCAT function that is available in mysql:
select i.item_name, group_concat(c.category_name) as categories
from items i
inner join items_categories ic on i.id = ic.item_id
inner join categories c on ic.category_id = c.id
group by i.item_name
I won't write it for you, but you need to use group_concat() function (MySQL).
I must say I did not test this query, but it should be something similar to the following:
SELECT i.Id, i.Item_name, GROUP_CONCAT(c.Category_Name) AS category_list
FROM Items i
JOIN Items_categories ci ON ci.Item_id = i.Id
LEFT JOIN Categories c ON c.Id = ci.Id
GROUP BY i.Id
Note that you can use GROUP_CONCAT to create a comma seperated list.
SELECT i.Item_Name, GROUP_CONCAT(c.Category_Name) AS Category_List
FROM Items AS i
LEFT OUTER JOIN (
Items_Categories AS ic
INNER JOIN Categories AS c ON ic.Category_id = c.Id
) ON i.Id = ic.Item_id
GROUP BY i.Id;
I'm really sorry for the first post as i didn't explain everything.
Basically i have 3 tables, One for posts, One for Categories, & Another to link categories with posts.
I want in a single MySQL query to select posts that are under a specific category.
posts(id,title,body)
---------------------
125,Some title,Blah blah
categories(id,name)
---------------------
1,politic
2,entertainment
linker(categoryid,postid)
---------------------
2,125
I want in single query to fetch posts in the entertainment category by example, what to do?
Thanks
select
p.*
from
posts p
inner join linker l on l.postid = p.id
inner join categories c on c.categoryid = l.categoryid
where
c.name = 'entertainment'
The following SQL statement should provide you with a basis for what you are trying to do.
select p.*
from posts p
inner join linker l
on l.postid = p.id
inner join categories c
on l.categoryid = c.id
where c.name = 'entertainment'
If a post belongs to 2 categories, you can still use pinkfloydx33's query with DISTINCT in the select statement:
select
DISTINCT p.*
from
posts p
inner join linker l on l.postid = p.id
inner join categories c on c.categoryid = l.categoryid
where
c.name = 'entertainment'
The result set will show only one record.
It's the same exact thing, you just have to join 3 tables intead of 2 :
SELECT P.id post_id,
P.title,
P.body,
C.id category_id,
C.name
FROM posts P
INNER JOIN linker L
ON P.id = L.postid
INNER JOIN categories C
ON L.categoryid = C.id
WHERE C.name = 'Category'
Don't be afraid to do your own tests. If you understand how to join two tables, you should understand how to join three, four and more.
If you are specifying only one category in the WHERE clause, then the result will be a single row for each post ID.
Either way you can use DISTINCT or GROUP BY when the result could be more than one row per ID, but in that case i prefer the second one (GROUP BY).