I have a blog with 2 table. First posts table with a key category_id and categories table. In a page I want to show all categories with count of their posts. I write this query but it have a problem. It did not show categories with no posts. in other word categories with 0 posts did not appear in the results.
And can you help to write this in eloquent system in laravel
SELECT categories.* , Count(posts.total) as total
FROM categories
LEFT JOIN
(
SELECT * , COUNT(*) as total from posts GROUP By posts.id
) as posts
ON posts.category_id = categories.id
Try following query:
SELECT categories.* , IFNULL(Count(posts.id),0) as total
FROM categories
LEFT JOIN
posts
ON posts.category_id = categories.id
Group by categories.id;
Related
I'm making a blog. I have 2 tables, one for posts and the other for categories.
I want to display the category name, category date and the number of posts in each category. I have problems to display the number of posts in each category.
In posts table I have a column called cat_id which is equal to category.id
I have these 2 MySQL queries:
mysql_query("select Count(posts.id) as NumberOfPosts, cat_id from posts group by cat_id");
And
mysql_query("select name, date from categories");
I don't know how to have combine these two queries into one query. I'm using PHP.
You could use a join:
SELECT name, date, NumberOfPosts
FROM categories c
JOIN (SELECT cat_id, COUNT(*) AS NumberOfPosts
FROM posts
GROUP BY cat_id) p ON c.id = p.cat_id
EDIT:
To include categories with no posts, you could use a left join instead of regular join. You just need to handle the nulls you'd get for NumberOfPosts, e.g., by using coalesce:
SELECT name, date, COALESCE(NumberOfPosts, 0) AS NumberOfPosts
FROM categories c
LEFT JOIN (SELECT cat_id, COUNT(*) AS NumberOfPosts
FROM posts
GROUP BY cat_id) p ON c.id = p.cat_id
This can be question which can ask on this site but I unable to find answer for it.
My question is that I have 3 tables
a . Product table
b. category table
c. product_category table
Any product can have multiple categories
So if i want to know all products which contain any category so i can use mysql query like
Select *
From products
left join product_category on (product.id = product_category.product_id)
Where category id in (45,56,78)
but if I want all only those products which have all these categories then how i find it ?
Select p.id
from products p
join product_category pc on p.id = pc.product_id
where category_id in (45,56,78)
group by p.id
having count(distinct category_id) = 3
I have categories table:
cat_id
cat_name
Than categories - posts relationship table cat_rel:
cat_rel_id
cat_id
post_id
And posts table:
post_id
post_title
post_content
Now I have data in all these tables, I need to pull out categories without to repeat those that have more than 1 post. I get somehow category repeated if it has more than 1 post, eg. categories like:
php, python, c++, java, ruby
if I have 2 posts under PHP, I will get:
php
python
php
java
and this is the query I run:
SELECT categories.cat_name, cat_rel.post_id
FROM categories
LEFT JOIN cat_rel ON cat_rel.cat_ID = categories.cat_ID
Any help about making those categories not to repeat, would be appreciated
Use DISTINCT
Have a look here:
SQL SELECT DISTINCT Statement
This would list the categories with more than one post:
SELECT categories.cat_name as Category
, count(distinct cat_rel.post_id) as PostCount
FROM categories
LEFT JOIN cat_rel
ON cat_rel.cat_ID = categories.cat_ID
GROUP BY categories.cat_name
HAVING count(distinct cat_rel.post_id) > 1
Try this:
SELECT DISTINCT categories.cat_name, cat_rel.post_id
FROM categories
LEFT JOIN cat_rel ON cat_rel.cat_ID = categories.cat_ID
So I have two tables, categories and designs. I want to construct a query that will fetch all categories, along with the count of any sub categories (categories.parent_id equal to the categories.id) AND the count of any designs (design.category_id equal to categories.id)
If I try to just get one of these counts, everything works fine, but when I try for both with the following code, the count for both is the same number (and not the correct number) for either.
$this->db->select('categories.id AS id, categories.parent_id AS parent_id, categories.title AS title,
categories.description AS description, categories.img_path AS img_path, COUNT(designs.id) AS design_count,
COUNT(sub_categories.id) as sub_category_count');
$this->db->from('categories');
$this->db->join('designs', 'categories.id = designs.category_id', 'left');
$this->db->join('categories as sub_categories', 'categories.id = sub_categories.parent_id', 'left');
$this->db->group_by('categories.id');
Any help will be much appreciated, cheers!
Assuming that the root categories do not contain designs, here is the query that returns the necessary information:
SELECT category.id, category.title, subcategory.id, designs.id
FROM categories category
LEFT JOIN categories subcategory ON category.id = subcategory.parent_id
LEFT JOIN designs ON subcategory.id = designs.category_id
WHERE category.parent_id IS NULL
Now all you need to do is to apply grouping:
SELECT category.id, category.title, COUNT(DISTINCT subcategory.id), COUNT(designs.id)
FROM categories category
LEFT JOIN categories subcategory ON category.id = subcategory.parent_id
LEFT JOIN designs ON subcategory.id = designs.category_id
WHERE category.parent_id IS NULL
GROUP BY category.id, category.title
The key here is the use of COUNT(DISTINCT ...).
SELECT c.id,c.title,
IFNULL(sc.counted,0) AS subcategories,
IFNULL(d.counted,0) AS designs
FROM categories c
LEFT JOIN
( SELECT parent_id,COUNT(*) AS counted
FROM categories GROUP BY parent_id ) sc
ON c.id=sc.parent_id
LEFT JOIN
( SELECT category_id,COUNT(*) AS counted
FROM designs GROUP BY category_id ) d
ON c.id=d.category_id
WHERE c.parent_id IS NULL ;
should get you the desired numbers as raw SQL.
What im trying to do was to list all categories and their posts but only limit posts per category. And exclude a category without any posts.
I did this with two queries though, get all the categories that have posts, loop the results and get X number of posts per category ID.
How can I do this in just 1 query?
EDIT: this is what I accomplished so far..
SELECT p.post_id, c.category_id
FROM category as c
JOIN posts AS p ON p.category_id = c.category_id
WHERE
FIND_IN_SET(p.post_id, (
SELECT SUBSTRING_INDEX(a.post_ids, ',', 10)
FROM
(
SELECT GROUP_CONCAT(b.post_id) AS post_ids, b.category_id
FROM posts as b
GROUP BY b.category_id
) AS a
WHERE a.category_id = c.category_id
))
To exclude all categories without any posts do an inner join between category and post. If you want to limit the number of rows returned, use the LIMIT command.
how about something like this
SELECT `category_name`
FROM `categories`
WHERE `posts` !=0
LIMIT 0 , 30