mysql row counter - php

I have a mysql table. It has auto increment on the id. but I regularly delete rows so the numbers are all over the place. I need to get the last n rows out, but because of deletions, the common way of using the max of the autoincremented id column doesn't work well...
1 - Is their another way to get the bottom 50?
2 - Is their a way to get rows by actual row number? so if I have 4 rows labelled 1,2,3,4 delete row 2 then it will become 1,2,3 rather than 1,3,4?

SELECT ... ORDER BY id DESC LIMIT 50

SELECT *
FROM TABLE
ORDER BY id DESC
LIMIT 50
EDIT
To pick the last 50, but sort by id ASC
SELECT X.*
FROM ( SELECT *
FROM TABLE
ORDER BY id DESC
LIMIT 50
) X
ORDER BY X.id

1 - First get total row count like
SELECT COUNT(*) AS c FROM ...
then use
SELECT ..... LIMIT [start],[count]
2 - One idea is to use view , or procedure, but this is much more harder and may be used when there is no other way to avoid this

1 - Is their another way to get the bottom 50?
SELECT * FROM table_name ORDER BY record_id DESC LIMIT 50
2 - Is their a way to get rows by actual row number? so if I have 4 rows labelled 1,2,3,4 delete row 2 then it will become 1,2,3 rather than 1,3,4?
SELECT * FROM table_name

1 - Yes but it is ugly afaik, you do a
SELECT whateveryouwant FROM table ORDER BY yourprimarykey DESC LIMIT 50
the you fetch the rows into an array and reverse the array, in php :
$r = mysql_query('SELECT * FROM table ORDER BY primarykey DESC LIMIT 50');
$set = array();
while($row = mysql_fetch_assoc($r)) $set = $row;
$set = array_reverse($set);
foreach($set as $row) {
// display row ...
}
2 - You'll have to manage your primary key by yourself, its a bit risky ...

Related

How select next row pagination in sql

I'm sorry I'm weak for English.
i echo 2 row in each page . how echo next 2 row
SELECT *
FROM `mzmx_post`
JOIN mzmx_post_category
WHERE mzmx_post.id = mzmx_post_category.post_id AND zmx_post_category.category_id = 5
ORDER BY id DESC
LIMIT 2
You can use the two-arguments form of LIMIT to offset the result by a given number of rows, like:
SELECT *
FROM `mzmx_post`
JOIN mzmx_post_category ON mzmx_post.id = mzmx_post_category.post_id
WHERE mzmx_post_category.category_id = 5
ORDER BY id DESC
LIMIT 2, 2 -- fetch records 3 and 4
This gives you the second page. If you want the third page, then:
LIMIT 4, 2
And so on.
Note that I modified your query so the joining condition between the tables is placed in the ON clause of the join rather than in the WHERE clause.
Better add one extra column (e.g. mzmx_post_key bigint) of Long type in each table and have sequential value on that column. Use that column to fetch data from DB from page wise.
sqL suery should look like:
SELECT *
FROM `mzmx_post`
JOIN mzmx_post_category ON mzmx_post.id = mzmx_post_category.post_id
WHERE mzmx_post_category.category_id = 5 and mzmx_post_key> ##last record key##
ORDER BY mzmx_post_key ASC
LIMIT 2
The basic idea is to use
LIMIT n,o
where n is the results per page
o is the offset from the first result
for the p-th page the offset would be
o = p * n
where p = 0,1,2,....

how to retrieve all rows from a table starting from the n'th row

I want to retrieve all rows from a table starting from the n'th row.
For example, if the table has 20 rows and n=9, I want to retrieve all elements Where the first part of the retrieved elements are the elements from 9 to 20 and the second part are form 1 to 8.
[9,10,...,19,20,1,2,...,7,8].
At first,I thought that I can use 2 queries to do that using LIMIT and OFFSET .
//retrieve the 2nd group
SELECT * FROM Tname WHERE 1 LIMIT (Tsize-n+1) OFFSET (n)
//retrieve the 1st group
SELECT * FROM Tname WHERE 1 LIMIT (n-1)
Where I calculate Tsize-n+1, n and n-1 before, and after retrieving elements I combine the two arrays.
But I don't think that this is the optimal solution (I don't want to use more than one query. and calculating the number of elements in the table is consuming).
Is there a better way to do that?
I have a simple idea. Just select all rows, then read first n rows and finally read remaining rows to the end. Just that!
You can also try this :
(SELECT * FROM Tname WHERE id >= n)
UNION (SELECT * FROM Tname WHERE id < n)
You can use small trick to do this:
SELECT * FROM Tname ORDER BY id >= n DESC, id ASC
This way you have results in that order [9,10,...,19,20,1,2,...,7,8].
If that didn't work (you don't know what id must be used as boundary) you can rearrange results in PHP:
$n = 9;
$resultsArray = array_merge(
array_slice($resultsArray, $n),
array_slice($resultsArray, 0, $n)
);
just reverse order by any column and pass the offset and limit
$data = SELECT * FROM table;
in php
krsort($data);
$chunked_data = array_chunk($data,9);

Mysql select last 20 rows, with while loop

I have 50+ rows and each have an id, how do i get the last 20 records and display each ones information with php.
Is the best way to use a loop? I want it to display the results quick and not miss any rows, is a loop the best way to go then?
This is the code that I have
$result = $mysqli_log->query("SELECT * FROM `$usern`");
while( $row = $result->fetch_array() ) {
$credit = $row['credit'];
echo $credit;
}
The MySQL query being executed doesn't specify any "order" to the rows; MySQL is free to return the rows in any order it chooses, so it's possible that the "last 20" rows on one run of the query might differ from the "last 20" rows on a second run.
(We do observe repeated behavior when the statement is re-executed; it usually takes some DML operations, the addition of an index, or an OPTIMIZE table statement, to actually get a change in the results returned... but the point is, there is no "last 20" rows in the table. In MySQL, it's just a set of rows.)
To specify a specific sequence of the rows, add an ORDER BY clause to the query. Assuming that you want to use the unique id column to order the rows, and you want the last 20 rows, and you want them returned in ascending id sequence:
SELECT t.*
FROM ( SELECT u.*
FROM `$usern` u
ORDER BY u.id DESC
LIMIT 20
) t
ORDER BY t.id
And, yes, processing rows "in a loop" in PHP, just like you demonstrate, is a normative pattern.
To limit the number of queries use Limit and order them desc by your ID
Select *
From `$usern`
Order By ID Desc
Limit 20
To Flip them back in the forward order you can use a derived table
Select *
From (Select ID, Test
From test
Order By ID Desc
Limit 3) d
Order By ID Asc
If you need the newest 20 records, you have to ORDER DESC the result set by ID and then LIMIT that set result to 20 records.
So you can
use something like this:
$result = $mysqli_log->query("SELECT * FROM `$usern` ORDER BY `ID` DESC LIMIT 20");
while( $row = $result->fetch_array() ) {
$credit = $row['credit'];
echo $credit;
}
Another good approach, if you are using associative keys like $row['credit'], is to use featch_assoc instead of featch_array (if your framework provides such a function)

Most efficient way to calculate affected rows with a limit

I have a column result in my table and want to know how many rows are affected where result contains a specific number like '3' in the last 25 rows before a specific id.
Eg: Want to know how many rows have a result = 3 of the 25 rows before the id "500".
What is the most efficiƫnt way to reach this in Php and MySQL.
You can do that completely with SQL:
SELECT COUNT(x.result)
FROM (
SELECT *
FROM table
WHERE id < 500
ORDER BY id DESC
LIMIT 25
) x
WHERE x.result = 3
First you find all entries that are relevant to your query by specifying the search criteria. Then you limit this search to 25 items and sort it in reverse order. That should yield the 25 last elements. Finally you just do your COUNT() for items with a result value of 3.
SELECT COUNT(result)
FROM table
WHERE id < '$specificID'
AND result = 3
ORDER BY id DESC
LIMIT 25
Try this
SELECT count(*) FROM `your_table`
WHERE result LIKE '%3%'
AND id < 500
ORDER BY id ASC
LIMIT 25;

How do I fetch the last 15 rows in a table, then the 15 before that?

I want to return only the last 15 rows in my table, then the 15 before that.
Unfortunately while($rows = mysql_fetch_assoc($result)) where the query is SELECT * FROM table returns the data in all rows.
I thought about doing something like:
In my insert script
SELECT * FROM table then $selection_id = mysql_num_rows($result)-14 before inserting any data, then adding column named selection_id which would contain $selection_id, thus each set of 15 rows would have the same selection_id.
In my select script
SELECT * FROM table then $num_rows = mysql_num_rows($result)/15 then SELECT * FROM table WHERE selection_id='$num_rows' and SELECT * FROM table WHERE selection_id='$num_rows-1'.
I could then perform while(..) on both results as usual.
However, I'm not sure this is the most efficient way (chances are it's not), so if not, I'd really appreciate some suggestions to cut down the amount of code I'll have to use :)!!
Use a LIMIT clause in your query, order by your auto-incrementing primary key in descending order. E.g.
SELECT * FROM `table` ORDER BY `selection_id` DESC LIMIT 0,15
...will get the last 15 rows, and:
SELECT * FROM `table` ORDER BY `selection_id` DESC LIMIT 15,15
...will get the 15 rows before that.
Selecting the last 15 rows:
SELECT *
FROM `table`
ORDER BY `id` DESC
LIMIT 0,15
Selecting the 15 rows before the previous ones:
SELECT *
FROM `table`
ORDER BY `id` DESC
LIMIT 15,15
And you can continue in a while cycle.
You need to check out mysql LIMIT. To get the last 15, you'd need to know the number of total rows.
$offset=$rowcount-15;
$sql="SELECT * FROM mytable LIMIT $offset,15";
This is just for example, you'd want to make sure there are at least 15 rows, I'm not sure how mysql would deal with a negative offset. I'll let you figure out how to count the rows.
Edit:
Oh, haha, you could also just sort it descending, that will save you having to query twice.
SELECT * FROM mytable ORDER BY id DESC LIMIT 15;

Categories