Reversing the display of mysql_fetch_array on html page - php

I have a discussion type page, where users can enter their replies on different subjects. For this, I have a table name replies with fields replyID, topicID, userID, replybody, time
On the page, where I display the result, I use this php command:
$run = mysql_query("SELECT * FROM replies WHERE topicID = $topicnumber ORDER BY time DESC Limit 5");
while($data= mysql_fetch_array($run)){
// do formatting and display data
}
as you can see, the page initially displays only 5 replies on a topic (after which, if interested, user clicks to visit the page where all replies are displayed).
the thing is, the above code displays correctly the recent 5 replies, but I want to change the order of its display. It shows the recent most reply on top, and older replies are displayed as we go down, but I want to change this order, showing the recent most reply on bottom.
I think I'm missing a very simple point here, since most of the website have this feature where recent most comments go down, but hey, "no question is small".

I don't think that's very easy in sql.
I would just load the results in an array and use array_reverse() to reverse the order. Then you can loop through the array and display the values like you do now.
Otherwise I think you need to do 2 queries, one to get the total amount and then one to limit your result set to the last x items.

Use a nested query to reverse the order in SQL:
SELECT *
FROM (
SELECT * FROM replies WHERE topicID = $topicnumber ORDER BY time DESC Limit 5
) AS a
ORDER BY time ASC
The inner query will return your most recent 5 records, while the outer query will reverse the sort order of those 5.

Related

Complex SQL Query - Popular Content

So, I'm writing a query to select data from the database, and display it in an order of popularity. I understand that this is simple enough to do if it were just ordering it through something such as ORDER BY numLikes DESC or something, but in this case, I am wanting to order the content by numLikes and through datePosted.
How would I sort the content in a way that it displays the top content from today's date? If it sorted purely through numLikes, The top content would float to the top and stay there. I want this content to be sorted through a daily basis. This is to allow for a system where the user can choose popular posts from the past day, past week, past month, and all time top posts.
Could this be done through a single SQL query? Would an SQL multi-query have to be done? Is SQL powerful enough to do this, or is PHP required to play a role?
Thanks!
You just need to sort on datePosted first and then by numLikes. Something on the following lines:
SELECT * FROM tableName ORDER BY datePosted, numLikes DESC
If you want top post between a particular range, you can do:
SELECT TOP 1 * FROM tableName
WHERE datePosted BETWEEN [MinDate] AND [MaxDate]
ORDER BY datePosted, numLikes DESC
Replace [MinDate] and [MaxDate] with the dates you need, e.g. for the past week, they would be something like April-14 and April-20.

Is there a way to identify which data has been selected with the sql statement

I have a sql statement:
$feed=$conn->prepare("SELECT * FROM posts WHERE post_by=? OR id=? ORDER BY id DESC LIMIT 10");
$feed->bind_param("ii",$friend['id'],$like[id]);
$feed->execute();
The $friend['id'] is the id of a user's friend, $like[id] is the id of a like by the user's friend.
The posts fetched with this query appear in a page.
What I want is I want to know which all posts have been posted by the user's friends (Which all posts have been fetched using $friends['id']) and which all posts have been liked by the user's friends and appear in the feed(Which all posts have been fetched using $like['id'])
I want to know all possibilities I can try to achieve what I want.
I have tried varying my query with UNION ALL but it shows errors and I could'nt achieve what I want.
Currently there are no errors but I want the user to know how this post appeared in the newsfeed.
Hope you all get a good idea about my question and all types of hacks are also accepted as I want in someway to achieve the result I would also agree to change mt query nature.
Please comment for more info.
Thanks in advance.
SELECT *, post_by = ?postId AS post_by_friend
FROM posts
WHERE post_by = ?postId OR
id = ?friendId
ORDER BY id DESC
LIMIT 10
post_by_friend will be 1 if it matched the first condition, otherwise 0. I haven't benchmarked it, but this method should be faster than StuartLC's UNION suggestion.
What you can do is break the query up on its 'OR' clause into a UNION of two separate queries, and add a marker column to indicate whether the row was found by friend or by like:
SELECT *
FROM
(
SELECT *, 'Friend' AS HowFound
FROM posts
WHERE post_by= ?postId
UNION
SELECT *, 'Like' AS HowFound
FROM posts
WHERE id= ?friendId AND post_by <> ?postId
) x
ORDER BY id DESC
LIMIT 10;
You'll want to exclude rows which match both friend and post classifications from one of the selects, otherwise it will be reported twice (or, otherwise your app will need to combine them).
I'm no PHP guru, but I'm sure there is a way to name the parameters to allow the above exclusion.
The derived table is needed to order and restrict the overall result.

I need to select newest rows from a MySQL database, but verify that I am also returning a row with a given ID

I'm new to this, sorry if the title is confusing. I am building a simple php/mysql gallery of sorts. It will show the newest 25 entries when a user first goes to it, and also allows off-site linking to individual items in the list. If the URL contains an ID, javascript will scroll to it. But if there are 25+ entries, it's possible that my query will fetch the newest results, but omit an older entry that happens to be in the URL as an ID.
That means I need to do something like this...
SELECT * FROM `submissions` WHERE uid='$sid'
But after that has successfully found the submission with the special ID, also do
SELECT * FROM `submissions` ORDER BY `id` DESC LIMIT 0, 25`
So that I can populate the rest of the gallery.
I could query that database twice, but I am assuming there's some nifty way to avoid that. MySQL is also ordering everything (based on newest, views, and other vars) and using two queries would break that.
You could limit across a UNION like this:
(SELECT * FROM submissions WHERE uid = '$uid')
UNION
(SELECT * FROM submissions WHERE uid <> '$uid' ORDER BY `id` LIMIT 25)
LIMIT 25
Note LIMIT is listed twice as in the case that the first query returns a result, we would have 26 results in the union set. This will also place the "searched for" item first in the returned sort result set (with the other 24 results displayed in sort order). If this is not desirable, you could place an ORDER BY across the union, but your searched for result would be truncated if it happened to be the 26th record.
If you need 25 rows with all of them being sorted, my guess is that you would need to do the two query approach (limiting second query to either 24 or 25 records depending on whether the first query matched), and then simply insert the uid-matched result into the sorted records in the appropriate place before display.
I think the better solution is:
SELECT *
FROM `submissions`
order by (case when usid = $sid then 0 else 1 end),
id desc
limit 25
I don't think the union is guaranteed to return results in the order of the union (there is no guarantee in the standard or in other databases).

I'm trying to make a forum

So I have these tables:
Topics
id, title, date
Posts
id, title, text, date, user, topic_id
How should I structure it so that the first post, the topics text, is on top of all other posts in the topic? Sort them by date? Or is there a smarter way?
Yes, sort by date (or by post ID). How else would you do it with that database structure?
Query
mysql_query("SELECT * FROM posts SORT BY date ASC");
Actually now that I look at this you may want to add time and sort by time and date, so that way two posts in the same day are shown in the correct order. It is not very clean to sort by id.
When adding pagination, you will be using MySQL's LIMIT to choose the records for that page. So if you are showing 20 records per page the query would look as so.
1st page:
mysql_query("SELECT * FROM posts SORT BY date ASC LIMIT 0,20");
2nd page:
mysql_query("SELECT * FROM posts SORT BY date ASC LIMIT 20,40");
The first page is calling records 0 through 20.
The second page is calling records 20 through 40.
It will sort them by date and time (maybe) accordingly. I am interested in how your forum will turn out! Let us know!
Best of Luck!! Let me know if you have any questions or concerns.

Making MySQL return the table backwards

I want to make a simple news system using PHP and MySQL, right now I got a working post and read system but there is only one problem, I want it to show the 10 latest news but instead it shows the 10 oldest news.
My question is: Is there a way to make MySQL return the results from the bottom of a table or do I have to first get the number of posts and then limit it to the very last 10 ones?
Here is the insert (title and text is escaped and time is time(), poster is not done yet):
mysql_query("INSERT INTO news (title, poster, text, time) VALUES ('$newstitle', '1', '$newstext', '$time')") or die(mysql_error());
And to retrive it (addnews echos it):
$myqr = mysql_query('SELECT * FROM news LIMIT 10') or die("Error running news query: ". mysql_error());
while($myres = mysql_fetch_array($myqr))
{
addnews($myres['id'], $myres['title'], "admin", date('l jS F Y - H:i:s', $myres['time']), $myres['text']);
}
So, short: I want to read the database backwards, is it possible?
Check out the ORDER BY clause. It allows you to sort rows by a column in ascending or descending order. The following query will return 10 news items, sorted by time in descending order.
SELECT * FROM news ORDER BY time DESC LIMIT 10
Simple, just add an "ORDER BY" clause to your SQL, e.g.
SELECT * FROM news ORDER BY time DESC LIMIT 10
you need to modify your query to sort by the date it was created. something like
SELECT * FROM news order by time DESC LIMIT 10
should work for you. I think its worth noting that if you do not specify an Order by clause, the order in which results are returned is not guaranteed. Right now, you happen to be getting them ordered by the time they were inserted ascending, however you cannot safely assume that will always be the case.
Assuming that id is the primary key:
SELECT * FROM new ORDER BY id DESC LIMIT 10
Use an ORDER BY clause.
Could you not simply Order By time Descending before LIMIT 10?
use
SELECT * FROM news ORDER BY time DESC LIMIT 10
You could also use
SELECT TOP 10 FROM news ORDER BY time DESC
I believe. Not sure if the 'top' clause is SQL Server only, though.

Categories