how to get last 10 and then show random 5 - php

hello all i am a php developer and right now i am having a simple issue like i want to get the last 10 data out of my database table and then show random 5 out of them .
like see the code below.
$random=rand(0,18);
mysqli_query(
$connection,
"SELECT something1,something2
FROM `table`
where (id !='0')
ORDER BY time DESC
LIMIT 4 OFFSET $random");
this query selects last 4 updated fields randomely out of 18 but i want a something better solution to this

First, define "the last 10"; for now let's assume the last ten when ordered by time. So, that is in fact the first ten when I order them the order way (I guess you got that):
SELECT * FROM `table` WHERE (id != '0') ORDER BY time DESC LIMIT 10;
then we subselect that to randomize and limit:
SELECT * FROM (
SELECT * FROM `table` WHERE (id != '0') ORDER BY time DESC LIMIT 10;
) A ORDER BY RAND() LIMIT 5
Remember, your database is extremely powerful and fast, use it for any data-processing.

Not sure there is a great solution with Select. Your sample take 4 line in a row with an OFFSET which is not a truly random selection. You should limit your select to 10 and then get 5 row of the 10 by another php code.
$rows = mysqli_query($connection,
"SELECT something1,something2 FROM `table` where (id !='0')
ORDER BY time DESC LIMIT 10");
//then, get 5 random key from your array of row from the mysql select
$rand_keys = array_rand($rows, 5);

In case you prefer randomizing in PHP, you can use PHP's shuffle and array_slice.
<?php
$last_10_rows = mysqli_query($connection, "simple query to get last 10 rows");
shuffle($last_10_rows); // randomize the array
$random_5_rows = array_slice($last_10_rows, 0, 5); // take first 5
?>
For

Related

How to select the top third row in mysql

Guys am trying to select the top/recently third row, i tried this one but it doesn't work, where do i make mistake ?
<?php
$sql = "SELECT * FROM songs ORDER BY id ASC LIMIT 1,2;";
$result = mysqli_query($con, $sql);
$resultCheck = mysqli_num_rows($result);
if (mysqli_num_rows($result) > 0) {
while ($row = mysqli_fetch_assoc($result)) {
echo $row['artist'];
}
}
?>
Use OFFSET:
SELECT * FROM songs ORDER BY id ASC LIMIT 1 OFFSET 2
The shorthand (which you are using) is reversed, so OFFSET is first then LIMIT:
SELECT * FROM songs ORDER BY id ASC LIMIT 2,1;
Use OFFSET
Here the limit 1 It simply means and you need one record
and the offset means skip the first 2
SELECT * FROM songs ORDER BY id ASC LIMIT 1 OFFSET 2
The parameters you use after limit should be reversed.
The first parameter is offset, and the second parameter is number of record you want.
SELECT * FROM songs ORDER BY id ASC LIMIT 2,1
This is just my opinion--
Sorting like this should always be done in client software.
Extract the data - remove the ORDER BY for your SQL...
Sort it in your client, and select and return the third line to the caller.
You will get better scalability and maintainability than driving all of this through an SQL query.
This is my go-to approach when solving these types of problems through custom software and it has been proven out over time.
Think about this:
Select ID from songs
get the id's into your code, and sort them there. Then chose the third one in the list. Then:
select title, author, artist, ... from songs where ID = VALUE FROM ID ABOVE
Yes, you are hitting the database twice, but these are two very efficient queries and that will perform better as your database scales, than the fancy order by you propose.

Mysql select list after a specific id

I'm trying to find a solution to select a list of rows coming after a certain Id from an ordered list.
For example, first I select 1000 rows. Then, on a subsequent request, i want to fetch another 1000 rows coming from after the last id of the first request. I know i can do it with limit, but suppose there has been 100 rows added between the first and second request, there will be 100 rows that will be from the first request.
Both queries will be ordered by the date of the entries.
Here's an example of the query I thought of:
$query = "SELECT * FROM table WHERE id AFTER $id ORDER BY date DESC";
$query = "SELECT * FROM `table` WHERE `id` > '$id' ORDER BY `date` DESC LIMIT 1000";
Two ways to do this:
WHERE
"SELECT * FROM `table` WHERE `id` > '$id' ORDER BY `date` DESC LIMIT $length"
LIMIT
"SELECT * FROM `table` LIMIT $start, $length"
$query = "SELECT * FROM table WHERE id > $id ORDER BY date LIMIT 1000";
You're asking about logic, not code so here it is.
The first request selects the first 1000.
$query = "SELECT * FROM the_table ORDER BY `date` DESC LIMIT 0,1000";
NB date is a reserved word so needs escaping if you've called a column "date" which you shouldn't.
$rs=$db->selectMany($query); // replace this with however you select the rows. $rs is results set
Do stuff with PHP and save the maximum id. They may not be in order.
$maxid=0;
foreach ($rs as $r){
// whatever you need to do with your results
$maxid=max($maxid, $r->id);
}
Your subsequent select uses the last id
$query = "SELECT * FROM the_table WHERE id > $maxid ORDER BY date DESC LIMIT 0,1000";
BUT you need to take note that you're ordering by date and using id to find a breakpoint which sounds like it would cause data to be missed.
Perhaps you mean to use WHERE`date`> $maxdate? If so you can figure that out from the code given.

Total of an array using only top 3 values

With help from a fellow member I have been able to add together the values of an array called by a MySQL query. However, the code I have is adding up all values.
$top_1st = mysql_fetch_array(mysql_query("SELECT SUM(1ET)/10 AS top_1st
FROM scoring_data WHERE Competition='$competition' AND Club='$row[Club]'
AND Team='$row[Team]' ORDER BY 1ET DESC LIMIT 0, 3"));
echo $top_1st[0] ;
I have used
LIMIT 0, 3
as I only want to add up the highest 3 values from the query returned, but this doesn't seem to work.
Apologies if there is a simple solution; novice skills really being put to the test!
EDIT
Advice from #marc-b (thanks) has led me to this, however it is giving a blank return.
$top_1st = mysql_fetch_array(mysql_query("
SELECT SUM(1ET)/10
FROM (
SELECT 1ET AS top_1st FROM scoring_data WHERE Competition='$competition' AND
Club='$row[Club]' AND Team='$row[Team]' ORDER BY 1ET DESC LIMIT 0, 3 ) "));
echo $top_1st[0] ;
You need to get the top 3 values first, then sum in another query, e.g.
SELECT SUM(foo)
FROM (
SELECT whatever AS foo
FROM ...
LIMIT 3
)
The limit has to be applied in the inner query. Otherwise you'd be summing up to a single row, which would then fall within the 3-row limit anyways.

PHP & MySQL - Limiting an array

I'm trying to limit the array mysql_fetch_assoc($query), and am unsure on how I would go about it.
$query = mysql_query('SELECT * FROM table ORDER BY id DESC');
while($output = mysql_fetch_assoc($query))
{
//do something
}
Do you add a counter or something? How do you add this counter?
I'm really confused about mysql_query and mysql_fetch_assoc. Please Help!
After your ORDER BY id DESC, add LIMIT 100 (or whatever number you want). For the next 100 rows, use LIMIT 100,100, then LIMIT 200,100 and so on.
You can limit the results directly in the SQL query. To get the top 100 records do
SELECT * FROM table
ORDER BY id DESC
LIMIT 100
Use LIMIT
SELECT * FROM table ORDER BY `id` DESC LIMIT 10;
Haven't you seen phpMyAdmin always limiting to 30?

Mysql Order by Tweak

I have a database with nearly 100 fields.
DB structure is
id | comment | time
I need to fetch only 5 newest record (I can get those records using ORDER by time DESC). But while printing them I need to print the oldest of those 5 records first and proceed in reverse in a way that the newest record will be printed last.
SELECT s.* FROM (
SELECT id, comment, time FROM table1
ORDER BY time DESC
LIMIT 5 ) as s
ORDER BY s.time ASC
Ok, after fetching result set in ascending order with a limit of number of rows
you can do this to print them in reverse order (descending order)
$data= array();
while ($row = mysql_fetch_assoc($result)) {
$data[] = $row;
}
$records = array_reverse($data);
OR
This could be done with mysql_data_seek
Directly taken from here
for ($i = mysql_num_rows($resultset) ā€“ 1; $i >= 0; $iā€“) {
mysql_data_seek($resultset, $i);
$row = mysql_fetch_assoc($result);
echo $row['abc'] . ' ' . $row['xyz'] . "\n";
}
You can use PHP's array_reverse() function on your result list.
http://php.net/manual/en/function.array-reverse.php
You can use also something like this:
select * from (select * from table_name where 1=1 order by time desc
limit 5) as tbl order by tbl.time;
Edit if you have a lot of accesses to this statement it would be much better to represent it as materialized view. Though there are no materialized views in mysql it is possible to simulate them (http://lists.mysql.com/mysql/207808)
Using a materialized view or a simulated materialized view will seriously outperform the suggested php approaches. Most of the mentioned ones consume to much memory anyways .
I guess you could do something along the lines of (untested):
SELECT
*
FROM (
SELECT
id, comment, time
FROM
table
ORDER BY
time DESC
LIMIT 5
)
ORDER BY
time ASC
UPDATE
Apparently, the "derived table must have its own alias" (error #1248). Other answers have already done this, so I'll jump on the bandwagon. Below you'll find the revised (and tested) query:
SELECT
derived.*
FROM (
SELECT
id, comment, time
FROM
table
ORDER BY
time DESC
LIMIT 5
) AS derived
ORDER BY
derived.time ASC
By the way, this is supported as of MySQL 4.1.

Categories