I'm working with php and I want to do a next button that's step to the next 10 records (like when you browse question with stackoverflow)
I don't know how to do that but I'm thinking to do it with Top n record ? Do you think that's a good idea ? Any suggestion?
As for doing it in PHP, you can easily make the button send a POST or GET request for the starting amount. For instance, a user would make the initial request and that is just yoursite.com/search.php, and the next button would send them to the same page with the same search criteria only send an additional field of "start", (i.e. yoursite.com/search.php?start=10). And in the code, you can simply check for it:
if(isset($_POST['start'])) {
//code to add to the search string to start at $_POST['start']
}
Edit 1: This article is the best I could find as to how to replicate MySQL's LIMIT function. Also, this one has a more definitive query to reference, but it's the same idea.
I know in MySQL you can use LIMIT X, Y where X is the lower bound of the return and Y is the upper bound. So if you wanted to return 10-20 you would use LIMIT 10, 20. Not sure what the MS-SQL equivalent is.
doesn't mssql have something like LIMIT in mysql? so you could do:
select xxx from yyy LIMIT 0,10
for first 10 results, then do LIMIT 10,20 for next 10 results etc.
You can use MySQL's limit
Set a variable called:
$limit = 10;
$pl = $_GET["page"] * $limit;
if(!isset($_GET["page"]) || $_GET["page"] == 1)
{
$pl = 0;
}
and in your query do
$sql = sprintf("SELECT * FROM table LIMIT %d,%d"
mysql_real_escape_string($pl),
mysql_real_escape_string($limit));
Btw this is from memory but i think it works.
Would this be any help to you?
$count=$_POST[page]*10;
for MySQL:
$rowsPerPage = 10;
$offset = ((int)$_GET['page'] - 1) * $rowsPerPage;
$result = mysql_query(
sprintf('select xxx from yyy LIMIT %d,%d', $offset, $rowsPerPage)
);
Related
I am developing an android app where i want to fetch 5 records each time using this query.
SELECT *from contest_table WHERE created_by='$me' LIMIT 5;
Now i get 5 records , but i want to fetch more 5 (next) records from data base when i click on "FETCH-MORE-RECORD" button inside the app
You can use OFFSET :
SELECT * from contest_table WHERE created_by='$me' LIMIT 5,5;
This will return 5 more rows, from position the 6th row (6-10).
The first number is to declare the start position of the fetch, and the second one is two declare how many to fetch.
This could also be written like this:
SELECT * from contest_table WHERE created_by='$me' LIMIT 5 OFFSET 5;
You will have to give a limit start and range. It will look as follows:
SELECT *from contest_table WHERE created_by='$me' LIMIT 5, 5;
To get first 5 records
SELECT * from contest_table WHERE created_by='$me' LIMIT 0,5;
To get next 5 records
SELECT * from contest_table WHERE created_by='$me' LIMIT 6,5;
Like wise you can change the starting point increasing it by 5.
So here is the solution. You need to keep the track of the off. So delcare a static variable for store the off. also update the offset after every click so next time you get right result.
public static int offset=5;
Then use this query with your listener;
SELECT * from contest_table WHERE created_by='$me' LIMIT 5,5;
It's a simple logic, Which I am representing as PHP codes, You request for first page from android by including page 1. in URL
http://SITENAME.COM/index.php?task=articles&page=1
You grab the result coming from URL like here
$page = $_GET['page'];
$max = 5; //As you want to retrieve 5 results only
And here define $start from where to start retrieving values
$end = $page * $max;
$start = $end+1 - $max;
Your query will be like
SELECT * FROM table order by column desc limit $start, $max //start will be 1 and max value to retrieve will be 5
After that you request page 2 and URL will be
http://SITENAME.COM/index.php?task=articles&page=2
and again in the query $start will be 6 and max value to retrieve will be 5 that is $max
Hope this helps, This is what the logic behind pagination.
When I run this query on phpmyadmin
SELECT *
FROM `product_stock`
WHERE `product_warehouse_id` =5
LIMIT 100000
it loads the data by section 50 by 50 till its stops. But when i do it in a normal php page it takes a while to load and sometimes i get server error. How can I aproach something similar to the way phpmyadmin loads the result?
http://www.tutorialspoint.com/php/mysql_paging_php.htm
this is tutorial how to add paging on mysql long queries.
The MySQL LIMIT takes a couple of possible arguments. A single value specifies to return all of those results to the caller. If you pass two values:
LIMIT 0, 50
Then you're passing the start row and the page size. The 10000 in your example is really just a short form for:
LIMIT 0, 10000
See the MySQL help documents on SELECT for some more detail.
I recommend if you're not going to use all data for all columns, do not use:
SELECT * FROM tablename WHERE 1 AND fieldkey = 'value'
If the data size is very large, causes performance problems in Mysql.
Use:
SELECT field1, field2, field3 FROM tablename WHERE 1 AND fieldkey = 'value'
In the SELECT statement, use comma separated names of the columns you want to display, this will help you the server to respond faster without problems and you can paginate through the results easyly.
Also verify that the data on "fieldkey" are indexed, this helps to the query to work faster.
You can paginate the results of your query with something like this:
php- Paginate data from array
This is what I wanted I had to do it with logic at the end it works, below the sample code:
while ($limit <= 1000){
$q1 = "SELECT *
FROM product_stock
WHERE product_warehouse_id = 5
LIMIT $start, $limit";
$r1 = mysql_query($q1) or die(mysql_error());
while($stock_info = mysql_fetch_assoc($r1)){
echo $stock_info[product_stock_id]."<br />";
}
$start = $limit + 1;
$limit += 50;
}
So I have an area where people can write their own query against my database, but I want to limit the returned results (much like PhpMyAdmin).
So I need to check $_POST['query'] to see if has a limit statement, if it does, make sure it's under 30, say. If there is no limit, I need to add it.
How would I do this?
Ignoring risks ... I think the best is to use the query as a subquery and apply limit. So you avoid evaluating the query .
SELECT *
FROM (
SELECT *
FROM 'table'
LIMIT 0 , 100
) AS query
LIMIT 0 , 30
You can use preg_* functions to check the query and inject your preferred limit.
EDIT: I totally ignored possible uses of the LIMIT keyword. Here's the edited version.
$query = 'SELECT * FROM aa LIMIT 100,20';
$limit = 20; // predefined max limit
// possibilities:
// LIMIT N[,N]
// LIMIT N OFFSET N
preg_match('~(?<=\blimit\s)\s*(?<limit>\d+)\s*(,\s*\d+|\soffset\s+\d+)?\s*$~i',$query,$limitStr);
if (isset($limitStr['limit'])) {
$maxLimit = min((int)$limitStr['limit'],$limit);
// user might have already limited it so this is
// just to make sure it does not exceed your max.
$query = preg_replace('~(?<=\blimit\s)\s*\d+\s*(,\s*\d+|\soffset\s+\d+)?\s*$~i',$maxLimit.'$1',$query);
} else $query .= " LIMIT $limit";
echo $query;
will output SELECT * FROM aa LIMIT 20,20
With the first query in the following code I am looking for the checkings made in Berlin under the game number two.
With the second query I want to give points for each of the checkings.
As you will see I am using the function SUM. But let's say that I have 2 checkings and the points for each checking are 50. Well, instead of echoing 100, with this code I echo 5050
What is wrong with it?
Thanks a lot
THE CODE IS CORRECTED AND WORKING, JUST IN CASE SOMEBODY NEEDS IT. Thanks to all
$querya = "SELECT * FROM checkins where gamesid=2 and city='Berlin'";
$resulta = mysql_query($querya) or die(mysql_error());
$sumOfPoints = 0;
while($rowa = mysql_fetch_array($resulta)){
$n = $rowa['venuesid'];
$queryb = "SELECT venuesid, SUM(points) as sumpoints from venues where venuesid='".$n."' GROUP BY venuesid ORDER BY venuesid";
$resultb = mysql_query($queryb) or die(mysql_error());
while($rowb = mysql_fetch_array($resultb)){
$sumOfPoints += $rowb['sumpoints'];
}
}
echo "Total points is $sumOfPoints<br/>";
Some suggestions
Use SUM(points) AS sum (only for clarity when use the sum)
Check that points are numerical fields not varchar.
points must be a string, you need to cast it
SUM(cast(points) as int)
and then follow Gaurav's point about labeling the compute
You're getting 5050 because your script is echoing 50 in two iterations of the loop.
From the looks of it, your second query's GROUP BY clause is not grouping on venuesid when it should be. So, first try changing your GROUP BY clause to:
GROUP BY venuesid
If that doesn't give you the result you're looking for, then you should try running your query directly against the database with a static value for venuesid to see what you get back from it, then perhaps update your question and we can take it from there.
I have a table with roughly 1 million rows. I'm doing a simple program that prints out one field from each row. However, when I started using mysql_pconnect and mysql_query the query would take a long time, I am assuming the query needs to finish before I can print out even the first row. Is there a way to process the data a bit at a time?
--Edited--
I am not looking to retrieve a small set of the data, I'm looking for a way to process the data a chunk at a time (say fetch 10 rows, print 10 rows, fetch 10 rows, print 10 rows etc etc) rather than wait for the query to retrieve 1 million rows (who knows how long) and then start the printing.
Printing one million fields will take some time. Retrieving one million records will take some time. Time adds up.
Have you profiled your code? I'm not sure using limit would make such a drastic difference in this case.
Doing something like this
while ($row = mysql_fetch_object($res)) {
echo $row->field."\n";
}
outputs one record at a time. It does not wait for the whole resultset to be returned.
If you are dealing with a browser you will need something more.
Such as this
ob_start();
$i = 0;
while ($row = mysql_fetch_object($res)) {
echo $row->field."\n";
if (($i++ % 1000) == 0) {
ob_flush();
}
}
ob_end_flush();
Do you really want to print one million fields?
The customary solution is to use some kind of output pagination in your web application, showing only part of the result. On SELECT queries you can use the LIMIT keyword to return only part of the data. This is basic SQL stuff, really. Example:
SELECT * FROM table WHERE (some conditions) LIMIT 40,20
shows 20 entries, starting from the 40th (off by one mistakes on my part may be possible).
It may be necessary to use ORDER BY along with LIMIT to prevent the ordering from randomly changing under your feet between requests.
This is commonly needed for pagination. You can use the limit keyword in your select query. Search for limit here:
The LIMIT clause can be used to constrain the number of rows returned by the SELECT statement. LIMIT takes one or two numeric arguments, which must both be nonnegative integer constants (except when using prepared statements).
With two arguments, the first argument specifies the offset of the first row to return, and the second specifies the maximum number of rows to return. The offset of the initial row is 0 (not 1):
SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15
To retrieve all rows from a certain offset up to the end of the result set, you can use some large number for the second parameter. This statement retrieves all rows from the 96th row to the last:
SELECT * FROM tbl LIMIT 95,18446744073709551615;
With one argument, the value specifies the number of rows to return from the beginning of the result set:
SELECT * FROM tbl LIMIT 5; # Retrieve first 5 rows
In other words, LIMIT row_count is equivalent to LIMIT 0, row_count.
You might be able to use
Mysqli::use_result
combined with a flush to output the data set to the browser. I know flush can be used to output data to the browser at an incremental state as I have used it before to do just that, however I am not sure if mysqli::use_result is the correct function to retrieve incomplete result sets.
This is how I do something like that in Oracle. I'm not sure how it would cross over:
declare
my_counter integer := 0;
begin
for cur in (
select id from table
) loop
begin
-- do whatever your trying to do
update table set name = 'steve' where id = cur.id;
my_counter := my_counter + 1;
if my_counter > 500 then
my_counter := 0;
commit;
end if;
end;
end loop;
commit;
end;
An example using the basic mysql driver.
define( 'CHUNK_SIZE', 500 );
$result = mysql_query( 'select count(*) as num from `table`' );
$row = mysql_fetch_assoc( $result );
$totalRecords = (int)$row['num'];
$offsets = ceil( $totalRecords / CHUNK_SIZE );
for ( $i = 0; $i < $offsets; $i++ )
{
$result = mysql_query( "select * from `table` limit " . CHUNK_SIZE . " offset " . ( $i * CHUNK_SIZE ) );
while ( $row = mysql_fetch_assoc( $result ) )
{
// your per-row operations here
}
unset( $result, $row );
}
This will iterate over your entire row volume, but do so only 500 rows at a time to keep memory usage down.
It sounds like you're hitting the limits of various buffer sizes within the mysql server... Some methods you could do would be to specify the field you want in the SQL statement to reduce this buffer size, or play around with the various admin settings.
OR, you can use a pagination like method but have it output all on one page...
(pseudocode)
function q($part) {
$off = $part*SIZE_OF_PARTITIONS;
$size = SIZE_OF_PARTITIONS;
return( execute_and_return_sql('SELECT `field` FROM `table` LIMIT $off, $size'));
}
$ii = 0;
while ($elements = q($ii)) {
print_fields($elements);
$ii++;
}
Use mysql_unbuffered_query() or if using PDO make sure PDO::MYSQL_ATTR_USE_BUFFERED_QUERY is false.
Also see this similar question.
Edit: and as others have said, you may wish to combine this with flushing your output buffer after each batch of processing, depending on your circumstances.