Display 5 most recent forum posts - php

So I have 3 tables inside of my database, let's say 1_comments, 2_comments and 3_comments and I want to display the latest 5 posts of all 3 tables at once in PHP and sort by the most recent time. My code is:
<?php
$row="";
$link = mysql_connect("localhost","username","password");
mysql_select_db("database");
$query = "SELECT * from 1_comments ORDER by timestamp DESC limit 5";
$result = mysql_query($query);
while($row = mysql_fetch_array($result)) {
echo "<ul>";
echo "<li>".$row['comment']."</li>";
echo "</ul>";
}
mysql_close($link);
?>
So it's taking the most recent 5 posts from the comments row on 1_comments and sorting them by their most recent timestamp, but I can't seem to get it working for 1_comments, 2_comments and 3_comments all at once.

If all tables have the same structure you can use UNION.
Something like:
(SELECT * from 1_comments ORDER by timestamp DESC limit 5)
UNION
(SELECT * from 2_comments ORDER by timestamp DESC limit 5)
UNION
(SELECT * from 3_comments ORDER by timestamp DESC limit 5)
ORDER BY timestamp DESC limit 5
However, I would take a good look at the database structure and try to reduce the 3 similar tables to just one.

Related

Mysql build query with multiple constraints

I am trying to set up a query that outputs the 5 most read articles over the last 4hrs. However, if there are no new articles over the last 4hrs, the list will be empty. What I would like is a query that outputs 5 articles over the last 4hrs. If there are no 5 articles in the last 4hrs, but lets say only 2, I would like to add 3 more newest articles to the list (sorted by log_time).
So the query should always output 5 articles.
I am wondering if this can be done in one query.
$sqlCommand = "SELECT * FROM feeds where category like '$category' AND log_time > NOW() - INTERVAL 4 HOUR ORDER BY feed_hits DESC LIMIT 5";
$query = mysqli_query($myConnection, $sqlCommand) or die (mysqli_error());
While ($row = mysqli_fetch_array($query)) {
$fid1 = $row["id"];
$feed_id1 = $row["feed_id"];
$link1 = $row["link"];
$title1 = $row["title"];
$output .= '' . $title1 . '<br/>';
}
mysqli_free_result($query);
echo $output;
You can achieve this via a UNION query. The first half of the below query is simply your original query, which may return up to 5 matching records. The second half of the query returns an arbitrary number of records which are older than 4 hours. The entire query is then ordered by log time, with a limit of 5. This puts your recent target records first, with the older records taking any available positions should they be needed.
SELECT *
FROM
(SELECT * FROM feeds
WHERE category like '$category' AND log_time > NOW() - INTERVAL 4 HOUR
ORDER BY feed_hits DESC LIMIT 5) t1
UNION ALL
(SELECT * FROM feeds
WHERE category like '$category' AND log_time <= NOW() - INTERVAL 4 HOUR) t2
ORDER BY log_time DESC
LIMIT 5;
You could not limit for 4 HOUR and order by log_time limit 5
"SELECT *
FROM feeds
where category like '$category'
ORDER BY log_time DESC LIMIT 5";
and if you need ordered by feed_hits you can reorder the result set
"select * from ( SELECT *
FROM feeds
where category like '$category'
ORDER BY log_time DESC LIMIT 5 ) t order by feed_hits ";
Simply remove the time filtering and instead order by time, this will always give you the latest:
SELECT * FROM feeds WHERE category LIKE '$category' ORDER BY log_time DESC, feed_hits DESC LIMIT 5

How to get last row a value without using loops for MySql query in limited more than 1

I want to known how to get last row a value without using while loop for mysql query.
Select data:
$sql = "
SELECT *
FROM status
WHERE author = '$pname'
AND postdate >= '$lsposttime'
ORDER
BY postdate ASC
LIMIT 4";
$query = mysqli_query($conn, $sql);
I want to get 4th row postdate value withoutusing loops.
Not using this:
while ($row = mysqli_fetch_assoc($query)){
}
select *
from status
where author = '$pname'
and postdate >= '$lsposttime'
order by postdate asc LIMIT 3, 1
this will get the fourth row
You can use a query like this:
SELECT *
FROM (
SELECT *
FROM STATUS
WHERE author='$pname'
AND postdate >= '$lsposttime'
ORDER BY postdate ASC LIMIT 4
) tnp
ORDER BY postdate DESC LIMIT 1;
This will return the last row. So if the result only return 2 row it will give the second.
You can use offset in mysql for fetch data from exact place an order.
For your Requirement your query will looks like:
$sql = "
SELECT *
FROM status
WHERE author = '$pname'
AND postdate >= '$lsposttime'
ORDER
BY postdate ASC
LIMIT 1 OFFSET 4";
$query = mysqli_query($conn, $sql);
And for more use of offset you can discover from here

How to get ORDERED and limited rows form MySQL and randomize show order

Is possible, and how to ask MySQL for
SELECT * FROM my_table ORDER by row_id DESC LIMIT 8
get the last 8, newest record from my table, with randomized order for PHP showing method
$results = $mysqli->query($query);
while($row = $results->fetch_assoc()) {
echo $row['my_col_name'];
}
Colud I, and where put the rand() in my SQL query?
Without randomize I get last 8 rows ORDERED 10,9,8,7,6,5,4,3
I want to get in the following order:
9,7,5,4,6,10,3,8;
8,7,3,6,10,9,5,4
...
You can place it inside another select:
SELECT * FROM (SELECT * FROM my_table ORDER by row_id DESC LIMIT 8) t ORDER BY RAND()
Use a subquery:
SELECT t.*
FROM (SELECT t.*
FROM my_table t
ORDER by row_id DESC
LIMIT 8
) t
ORDER BY rand();

Deleting older database entries

I'm trying to keep the 10 most recent entries in my database and delete the older ones. I tried DELETE FROM people ORDER BY id DESC LIMIT $excess, but it just deleted the top 10 entries.
$query = "SELECT * FROM people";
$result = mysqli_query($conn, $query);
$count = mysqli_num_rows($result);
if ($count > 10) {
$excess = $count - 10;
$query = "DELETE FROM people WHERE id IN(SELECT id FROM people ORDER BY id DESC LIMIT '$excess')";
mysqli_query($conn, $query);
}
You can use this:-
DELETE FROM `people`
WHERE id NOT IN (
SELECT id
FROM (
SELECT id
FROM `people`
ORDER BY id DESC
LIMIT 10
)
);
Also your query is logically incorrect and you are fetching the records in descending order. i.e. Latest to older and you are deleting the most recent records. Use ASC instead.
Something like this? Gets the ten latest ids in the subquery, then deletes all of the other ids.
DELETE FROM people WHERE id NOT IN (SELECT id FROM PEOPLE ORDER BY id DESC LIMIT 10)
Your logic is all over the place, [you should ORDER BY ASC, not DESC] and your query will take ages if there are [for example] 10,000 entries because you'll have an IN clause with 9,990 entries to compare all 10,000 to.
Select the 10 most recent, and delete where NOT in.
DELETE FROM people
WHERE id NOT IN(
SELECT id
FROM people
ORDER BY id DESC
LIMIT 10
)
Maybe find the ID of the 10th element and then delete all rows which are older?

Select max 5 integers from set of 20

I'm trying to select the 5 most viewed articles out of a list of the 20 most recent entries in a table. My table structure is essentially this:
id | date | title | content | views
My first thought was just to use an inner select to get the 20 most recent articles, then select from that, but I have yet to have any luck.
//doesn't work (my version of mysql doesn't support LIMIT in sub queries)
$recent = "(SELECT id FROM news ORDER BY date DESC LIMIT 20)";
$result = $db->query("SELECT id, title, date, content FROM news WHERE id IN $recent ORDER BY views DESC LIMIT ".self::RECENT_MAX);
//neither does this (syntax error # 'OFFSET 20')
$recent = "(SELECT MAX(date) FROM news ORDER BY date DESC OFFSET 20)";
$result = $db->query("SELECT id, title, date, content FROM news WHERE date > $recent ORDER BY views DESC LIMIT ".self::RECENT_MAX);
Anyone got any suggestions on how you would structure this query?
I just tested this and it works
SELECT *
FROM (
SELECT *
FROM news
ORDER BY id DESC
LIMIT 0, 20
) lasttwenty
ORDER BY views DESC
LIMIT 0, 5
Server version: 5.0.51a-3ubuntu5.4
If you're having a lot of issues getting it to work through SQL, I'd suggest just grabbing the 20 most recent articles from the database, then process it in PHP to find the 5 most-viewed. You could either loop over the rows, or just load it all into an array and sort it.
Since I can't think of any way to do that in a single query, I suggest either selecting the top 5 in code, or doing it using two queries, something like:
$items = $db->query("SELECT id FROM news ORDER BY date DESC LIMIT 20");
$recent = array();
foreach ($items->fetchAll() as $item) { $recent[] = $item['id']; }
$recent = "('".join("','", $recent)."')";
$result = $db->query("SELECT id, title, date, content FROM news WHERE id IN {$recent} ORDER BY views DESC LIMIT ".self::RECENT_MAX);
Why don't you run the first (inner) query separately, and create the second query programmatically?
$ids = array();
$result = $db->query("SELECT id FROM news ORDER BY date DESC LIMIT 20");
while ($row = $result->fetch()) {
$ids[] = $row[0];
}
$ids = implode(',', $ids);
$result = $db->query("SELECT id, title, date, content FROM news WHERE id IN ($ids) ORDER BY views DESC LIMIT ".self::RECENT_MAX);
Or something of this nature...
Update: Or you could just simply fetch the first 20 sorted by date, then sort thr result array by views in PHP, and finally take the 5 topmost items (I guess this is what SilentGhost meant in the comment).
Try this...
select top 5 number from
(
select
top 20 (ID) as number
from
news order by date desc
)
as number
EDIT FOR MS SQL
Use the LIMIT for MYSQL

Categories