selecting multiple categories from database - php

I am working on a blog system where blogs are categorized and we can choose the category we want to. For this, I have to separate the tables blogs and categories. I know how to get blogs from all categories and from a single category, but I don't know how to get blogs from multiple but not all categories.
My code looks like this:
<?php
$query = ("SELECT blogs_id, title, body, posted_by, category FROM blogs INNER JOIN categories ON categories.category_id=blogs.category_id where category='cat1' ORDER BY blogs_id desc LIMIT 10");
$result = mysql_query($query) or die("error:".mysql_error());
while ($row = mysql_fetch_assoc($result)) {
$title = $row['title'];
$body = $row['body'];
$posted_by = $row['posted_by'];
?>
This code is for selecting a single category and it works well, but now I want to choose multiple (but not all) categories. I tried a few different options, but failed:
<?php
$query = ("SELECT blogs_id, title, body, posted_by, category FROM blogs INNER JOIN categories ON categories.category_id=blogs.category_id where category='cat1' AND category='cat2' AND category='cat3' ORDER BY blogs_id desc LIMIT 10");
This didn't work.

Use the IN clause:
WHERE category IN ('cat1', 'cat2', 'cat3')
Alternatively, you can use OR:
WHERE category = 'cat1'
OR category = 'cat2'
OR category = 'cat3'

Try OR in place of AND (in where condition). try this:
$query = ("SELECT blogs_id, title, body, posted_by, category FROM blogs INNER JOIN categories ON categories.category_id=blogs.category_id where category='cat1' OR category='cat2' OR category='cat3' ORDER BY blogs_id desc LIMIT 10");

Try this
$query = ("SELECT blogs_id, title, body, posted_by, category FROM blogs INNER JOIN categories ON categories.category_id=blogs.category_id where category IN ('cat1', 'cat2', 'cat3') ORDER BY blogs_id desc LIMIT 10");

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 do i use DESC limit 3 when i have joined two tables

I have joinend two tables and it workes like it should do but now i want to use DESC limit, but i dont know where i should put it
$query = 'SELECT * FROM posts INNER JOIN category ON posts.catid=category.id;';
$select_all_posts_query = mysqli_query($link, $query);
$query = 'SELECT * FROM posts INNER JOIN category ON posts.catid=category.id ORDER BY posts.catid=category.id DESC LIMIT 3 ';
$select_all_posts_query = mysqli_query($link, $query);
If you only want to limit your results you can just add LIMIT 3 to your query:
$query = 'SELECT * FROM posts INNER JOIN category ON posts.catid=category.id; LIMIT 3';
$select_all_posts_query = mysqli_query($link, $query);
Alternatively, if you are also trying to order your results is descending order you'll need to add and ORDER BY to the query as well:
$query = 'SELECT * FROM posts INNER JOIN category ON posts.catid=category.id; ORDER BY posts.id DESC LIMIT 3';
$select_all_posts_query = mysqli_query($link, $query);

How to (COUNT) get total rows belong to post using inner join php?

I am using inner join to list posts and their categories and comments,
Like this:
if($stmt = $pdo->prepare("SELECT * FROM posts
INNER JOIN categories ON posts.cat_id = categories.cat_id
INNER JOIN comments ON posts.post_id = comment_id
WHERE user_id = :sid")){
$stmt->execute(array('sid'=>$sid));
Then doing while loop to list them
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
And usaqe is :
$row['category'];
I want to get total rows of the comments belong to post and show them like :
Total comments on post : $row['total_coments'];
İs it possible ?
You can do this , assuming the comment_id is unique,
if($stmt = $pdo->prepare("SELECT posts.*,(select count(comment_id) from
comments)
as total_coments
FROM posts
INNER JOIN categories ON posts.cat_id = categories.cat_id
INNER JOIN comments ON posts.post_id = comment_id
WHERE user_id = :sid")){
$stmt->execute(array('sid'=>$sid));

Count posts as categories PHP & MYSQL

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"

MySQL count from intermediary table

I'm trying to find the most used categories in an intermediary table which contains two ids, I'm running this to find all the counts of posts against categories.
$data = $conn->query('SELECT * FROM category WHERE category_name ORDER BY category_name');
foreach($data as $row) {
$sql = "SELECT COUNT(p_id) FROM p_categories c,category ca WHERE c.category_id = ca.category_id AND category_name = :category_name";
$q = $conn->prepare($sql);
$q->execute(array(':category_name' => $row['category_name']));
$catco = $q->fetch();
echo '<p>'.$row['category_name'].' ('.$catco[0].')</p>';
}
This returns all the categories, but I want to limit it to only the top four categories having most p_id. I tried limiting the count query to 4 but that didn't work.
Here are the tables:
posts: p_id, p_name
p_categories: p_id, category_id
category: category_id, category_name
You can do this in a single query
$sql = "SELECT p_categories.category_id, COUNT(*) AS cnt, category.category_name
FROM p_categories
LEFT JOIN category
ON p_categories.category_id = category.id
GROUP BY `category_id`
ORDER BY cnt
DESC LIMIT 4"
$data = $conn->query($sql);
foreach($data as $row) {
echo '<p>'.$row['category_name'].' ('.$row['cnt'] .')</p>';
}

Categories