Get next post with SQL and PHP - php

I've made a very rough and basic CMS as a learning exercise. My next challenge is to create a pagination (next post, previous post).
Ideally, I need to get the next post, if post_status is set to published.
At the moment I get a post like so:
SELECT post_title, post_content, post_id, post_status
FROM posts
WHERE post_id='$id'
AND post_status='published'
In my mind, I would increment the $id on the PHP side, like $id++. So if I'm on post_id=19, I try and get post_id=20. However, what happens if that post is not set to published — how do I get the next entry, WHERE post_status='published'? This could be 21, 23, etc.

You can do this way, say you have an
$id = 19;
SELECT post_title,
post_content,
post_id,
post_status
FROM posts
WHERE post_status='published'
AND post_id > '$id'
order by post_id
LIMIT 1
This will check posts having id > 19 with post_status='published' and then get the next to 19 by ordering and limit 1
UPDATE
As danielsmile commented on getting the previous one for getting last one before $id = 19; would be pretty same as above
SELECT post_title,
post_content,
post_id,
post_status
FROM posts
WHERE post_status='published'
AND post_id < '$id'
order by post_id DESC
LIMIT 1

If the posts are ordered by id (maybe ordering by date would be better), You can get the next post using:
SELECT post_title, post_content, post_id, post_status
FROM posts
WHERE port_status = 'published'
AND id > $id
ORDER BY id ASC
LIMIT 1
That means - get all the posts that have higher id than the current one. Sort them by id ascending and get just the first one. So as a result, it gives You the first posts with the closest higher id.

Related

How to use a custom id when post an article in WordPress

WordPress' post_id is not continuous, so I want to use a custom post_id in wordpress when post an article.
For example, I want to post an article as |id=2in database wp_posts, I got the position ofid=1` , what do I need to do in my function? I add it to my theme's functions.php
function reuse_old_id(){
global $wpdb;
$lastID = $wpdb->get_var("SELECT ID FROM (SELECT ID FROM $wpdb->posts ORDER BY ID ASC) T WHERE NOT EXISTS (SELECT 1 FROM $wpdb->posts WHERE ID=T.ID-1) LIMIT 1");
$lastID++;
// I tried the following code but the it didn't work
$wpdb->query("ALTER TABLE $wpdb->posts AUTO_INCREMENT = $lastID");
}

ORDER before SELECT statement?

I have this query which works great
$sub_query = "SELECT * FROM posts WHERE post_status = 'published' AND
post_user = '{$out}' ORDER BY post_id DESC ";
The query brings back all of a specific users posts ordered by descending post id. The problem is it loops through every post user and orders them accordingly but I want the newest post overall not just the newest post per user.
Here is an image of the results to hopefully help explain better
You can see the query runs for a specific user and then moves on to the next user where I am trying to get the newest post id first
I have tried to follow this similar question but it brought back the same results.
$sub_query = "SELECT * FROM (SELECT * FROM posts ORDER BY post_id DESC)
T WHERE post_status = 'published' AND post_user = '{$out}' ";
Would I be able to order all of the selected posts first? Then use my where statement?
If you want the newest post per user, then remove the where and add a limit:
SELECT p.*
FROM posts p
WHERE p.post_status = 'published'
ORDER BY post_id DESC
LIMIT 1;
I did not understand if what you are looking for is
1) the list of the last post per user
2) the list of all posts sorted by the newest (regardless the user)
In both case you don't need to loop all users, you can extract data ordered just using the query itself (i strongely advise you on this solution).
option 1:
SELECT *
FROM posts
WHERE post_id IN (
SELECT MAX(post_id)
FROM posts
WHERE post_status = 'published'
GROUP BY post_user
)
ORDER BY post_user ASC
option 2:
SELECT *
FROM posts
WHERE post_status = 'published'
post_id DESC

Pulling latest post from table

All,
I am trying to display the latest post from my authors.
The posts are in one table, the author in another. The queries used were: join on a column called content_id, and I am trying to work with MAX(item_date) which is the date the post was published.
Here are some queries I am running and the output, I seem to be getting everything except the latest posts from all authors:
First (and this bit is working) we need to get information about the author:
$query="SELECT content_id, title, source_image, url FROM content_detail where approved='y'";
$result1 = $mysqli->query($query) or die($mysqli->error.__LINE__);
// GOING THROUGH THE DATA
if($result1->num_rows > 0) {
while($fetch=mysqli_fetch_array($result1)) {
$title=$fetch['title'];
$feed_rss=$fetch['url'];
$content_id=$fetch['content_id'];
$source_image=$fetch['source_image'];
Now on that basis lets get the posts, round 1:
$query2 = "SELECT item_id, item_title, MAX(item_date) as item_date from posts WHERE content_id='$content_id' GROUP BY content_id";
$result2 = $mysqli->query($query2) or die($mysqli->error.__LINE__);
if($result2->num_rows > 0) {
while($rows2=mysqli_fetch_array($result2)) {
$item_id = $rows2['item_id'];
$item_title = $rows2['item_title'];
$item_date = $rows2['item_date']; `
This pulls back an in interesting set of results, the latest date of a post from an author, but not the latest title!
I have tried GROUP BY item_title and content_id to no avail.
The following pulls back just records that have more than one date in the database, the problem is (as this is new) some authors only have one post, these are not being displayed:
$query2 = "SELECT item_id, item_title, item_date FROM posts AS a WHERE content_id = content_id AND item_date = (
SELECT MAX(item_date)
FROM rssingest AS b
)
";
I have tried:
ORDER BY DATE DESC LIMIT 1
at the end of my queries to no avail.
item_date is a DATE type in the table.
Any help would be greatly appreciated!
Thanks,
You are running this query to get the maximum date:
SELECT item_id, item_title, MAX(item_date) as item_date
from posts
WHERE content_id = '$content_id'
GROUP BY content_id;
Of course you don't get the right item_title. It is not mentioned in the group by clause and has no aggregation function. So, you are using a MySQL extension (this query would fail in other databases).
You can get the most recent title using the substring_index()/group_concat() trick:
SELECT max(item_id),
substring_index(group_concat(item_title separator '|' order by item_date desc), '|', 1) as last_title,
MAX(item_date) as item_date
from posts
WHERE content_id = '$content_id'
GROUP BY content_id;
This will return one row. But, if there is only one row that you want, you can do:
SELECT p.*
from posts p
WHERE p.content_id = '$content_id'
ORDER BY item_date desc
LIMIT 1;
The previous version will generalize if you add a group by statement.
You need to join your posts table with itself to grab only the newest post for each content_id (which I believe is the author).
$query2 = "SELECT posts.item_id, posts.item_title, posts.item_date from posts
join (select max(item_id) max_id, content_id from posts group by content_id) maxid
on maxid.content_id=posts.content_id and maxid.max_id=posts.item_id
WHERE content_id='$content_id' ";
This opens the door for further optimization. You could grab the authors and their last post in one run.
SELECT content_detail.content_id,
content_detail.title,
content_detail.source_image,
content_detail.url ,
posts.item_id,
posts.item_title,
posts.item_date
FROM content_detail
join posts on content_detail.content_id=posts.content_id
join (select max(item_id) max_id, content_id from posts group by content_id) maxid
on maxid.content_id=posts.content_id and maxid.max_id=posts.item_id
where content_detail.approved='y'
But this could be an overstatement. You should of course try it yourself :)

MySQL don't select a row

I need to get the titles of 3 recent posts, but leave out a specific one, if it comes up as one of the 3 most recent ones.
I got this:
SELECT
postID,
title
FROM
posts
WHERE
categoryID = $categoryID
ORDER BY
date DESC
LIMIT
3
This works fine, but I need to tell if to leave out the row where "postID = $postID"
"$postID" is the post that shouldn't be displayed and is defined before.
Thanks!
Add another condition to the where clause to filter that specific postId
SELECT
postID,
title
FROM
posts
WHERE
categoryID = $categoryID
AND
postID <> $postID
ORDER BY
date DESC
LIMIT
3
This should do the trick:
SELECT
postID,
title
FROM
posts
WHERE
categoryID = $categoryID
AND
postID != $postID
ORDER BY
date DESC
LIMIT
3
Am I understanding you correctly? You just want to omit the postID equal to $postID?
SELECT
postID,
title
FROM
posts
WHERE
categoryID = $categoryID
AND
postID <> $postID
ORDER BY
date DESC
LIMIT
3
This query returns the expected results using the <> operator:
SELECT
postID,
title
FROM
posts
WHERE
categoryID = $categoryID
AND postID <> $postID
ORDER BY
date DESC
LIMIT
3

How to get data from 2 tables? [duplicate]

This question already has answers here:
Querying 2 Tables in a single query
(3 answers)
Closed 8 years ago.
I am trying to create a website with an existing database.
The database has two tables, one of them contain the post info like title, id, content, etc etc,
the other table contains the post ID and the post category.
For example: I want to take a post from a specific category.
$sql = 'SELECT * FROM posts WHERE status = "publish" ORDER BY date DESC LIMIT 10';
This is a simple function, can some one help me please how to modify it, to get the category from the other table and the post info from the other table.
SELECT * FROM posts, posts_category WHERE category = 'category'
AND
status = 'publish'
AND
posts_category.post_id = posts.id
ORDER BY date DESC LIMIT 10;
$sql = "SELECT * FROM posts WHERE status = 'publish' AND pid IN (SELECT pid FROM pcategory WHERE ptype='category_name') ORDER BY date DESC LIMIT 10";

Categories