Count posts as categories PHP & MYSQL - php

I've this code...
$lesson = mysql_query("SELECT * FROM categories WHERE gr='exrcs' ORDER BY title");
$flesson = mysql_fetch_array($lesson);
do {
printf("<a href='exrcs?cat=%s'>%s</a>",$flesson['id'],$flesson['title']);
} while ($flesson = mysql_fetch_array($lesson));
This code will be "HTML, CSS, PHP" and other...
But I want this "HTML (2), CSS (14), PHP(8)" and other...
Here (2),(14),(8) amount posts on categories

Update your query:
SELECT title, count(id) total FROM categories WHERE gr='exrcs' group by title ORDER BY title
or
SELECT concat(title,' (', count(id) ,')') as title FROM categories WHERE gr='exrcs' group by title ORDER BY title

Use count and group by
"SELECT cat as title , count(*) FROM categories
WHERE gr='exrcs' group by title ORDER BY title"

"SELECT CONCAT(C.title,'(',COUNT(*),')') FROM categories C INNER JOIN post P ON C.ID= P.cat_id GROUP BY c.title"

Related

How to display several subcategories and their news in one query?

I have a news site and I am trying to include a block of news in it.
see the image please
I created a category call world news and added subcategories. (Travel, News, Art, Bussines)
I display them one by one, I mean I do a query for each news, that means 4 different queries like below :
$sql = "SELECT posts.post_catId,
posts.post_seo_url,
posts.post_desc,
posts.post_type,
posts.post_status,
posts.post_title,
posts.post_image_url,
categories.catId,
categories.catName,
categories.cat_seo_url
FROM posts
LEFT JOIN categories
ON posts.post_catId = categories.catId
WHERE post_catId = catId AND cat_seo_url = 'art'
AND post_status = ?
ORDER BY post_created_at DESC LIMIT 1";
$stmt = $pdo->prepare($sql);
$stmt->execute(['1',]);
if($stmt->rowCount() > 0){
while($row = $stmt->fetch()){
//here
}
}
My question is: is there a way to display them in one query ?
Edit : I want to display 1 news from 4 specific categories with one query instead of 4.
I know I can add a new row to categories table to secify which categories can be displayed.
You 'invert' the query, selecting the categories first and then joining to the posts table, constraining it by the post_seo_url field, like so:
$sql = "SELECT
categories.catId,
categories.catName,
categories.cat_seo_url,
posts.post_catId,
posts.post_seo_url,
posts.post_desc,
posts.post_type,
posts.post_status,
posts.post_title,
posts.post_image_url,
FROM categories
JOIN posts ON posts.post_seo_url = (
SELECT p.post_seo_url FROM posts as p
WHERE categories.catId = p.post_catId
ORDER BY p.post_created_at DESC LIMIT 1
)
WHERE post_status = ?"
Here's a method using ROW_NUMBER() function:
SELECT p.*,
categories.catId,
categories.catName,
categories.cat_seo_url
FROM
(SELECT
ROW_NUMBER() OVER (PARTITION BY posts.post_catId ORDER BY posts.post_created_at DESC) AS RN,
posts.post_catId,
posts.post_seo_url,
posts.post_desc,
posts.post_type,
posts.post_status,
posts.post_title,
posts.post_image_url
FROM posts
WHERE post_status = ? ) p
JOIN categories
ON p.post_catId = categories.catId
WHERE RN=1;
I've made the query on posts table to become a subquery with addition of ROW_NUMBER() function then JOIN it with categories table and added WHERE that only return row number = 1. I've changed the LEFT JOIN to JOIN because I don't see any reason to use LEFT JOIN in this operation. However, if there is a reason, please update it in your question.
Here's a demo fiddle

How to count total comment in a category not a topic

My database:
category (cat_id,cat_name)
topic (topic_id,cat_is)
comment(com_id,topic_is)
Now I want to count total comment in a category.
select cat_id, count(1) cnt
from category
join topic on cat_is = cat_id
join comment on topic_is = topic_id
group by cat_id

Display categories with number of posts

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

Displaying categories without repeating each that has posts

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

MySQL Subselect Limit

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

Categories