I am running a query from a table whose data gets refreshed (deleted and re-inserted) every 30 seconds.
I want my query (which outputs row count) to detect that the row count is null (or zero) and re-run the query. Maximum retries: 5.
And after 5th retries, if it's still zero, I want the row count to print "0".
I know it's a loop but I don't know how to loop it from within the if for row.
<?php
$con=mysqli_connect("HOST","USERNAME","PASS","TABLENAME");
$sql="SELECT id FROM candyshop WHERE candy <= 5 AND sugartype ='hard'";
$number = 0; //init count for loop
if ($result=mysqli_query($con,$sql))
{
$rowcount=mysqli_num_rows($result);
printf($rowcount); //print number of rows
mysqli_free_result($result);
$number = $number+1; //increment number for loop
}
mysqli_close($con);
?>
Use a do while loop and only leave the loop if the rowcount is higher than 0 or 5 retries have been reached.
<?php
$sql = "SELECT id FROM candyshop WHERE candy <= 5 AND sugartype ='hard'";
$count = 0;
$retry = 5;
do {
// Count the rows
if ($result = mysqli_query($con, $sql)) {
$count = mysqli_num_rows($result);
}
// Wait for 10ms
if ($count === 0) {
usleep(10000)
}
} while ($count === 0 && --$retry > 0);
mysqli_close($con);
This is however very bad practice, I would recommend looking for another approach. Why would you clear and then refill the table?
Still new to StackOverflow but can you try this?
<?php
$con=mysqli_connect("HOST","USERNAME","PASS","TABLENAME");
$sql="SELECT id FROM candyshop WHERE candy <= 5 AND sugartype ='hard'";
$number = 0; //init count for loop
if ($result=mysqli_query($con,$sql)) {
$rowcount=mysqli_num_rows($result);
printf($rowcount); //print number of rows
mysqli_free_result($result);
$number = $number+1; //increment number for loop
if ($number = 5) {
printf(0);
break 2;
}
}
mysqli_close($con);
?>
$i = 0;
do {
$result = mysqli_query($con, $sql);
$count = mysqli_num_rows($result);
} while ($count == 0 && $i++ < 5)
As i understood you are trying to write a Web Based Game. Actually your method is probably going to make database a little busy. You don't have to loop queries. If you are going to do it, we are talking about milliseconds here. Let's say your queries are generally giving results in 0.05 seconds that means for 5 query you are just going to have the data of 0.25 seconds.
You can write your game or whatever easily with COMET Programming. But if you decided to go with loop queries , there is only one thing you will do and it's for loop.
$rowcount=0;
do {
if ($result=mysqli_query($con,$sql)) {
$rowcount=mysqli_num_rows($result);
printf($rowcount); //print number of rows
mysqli_free_result($result);
}
} while(++$number<5 && $rowcount!=0);
that is basicaly the answer to your request, though it needs some more explanation to be useful.
Related
I didn't know exactly how to word this question but by do something I mean that I would like to hide or not show my "next" button that is shown below. I have a script that pulls all the images from MySQL and prints them to my page by 30 images per page and the next 30 will create a new page that is activated by my back/next buttons. My "back" button has a if statement if $startrow isn't >= 0 than it won't show but I would like the same concept with my next button when the last row in my database is shown and it hides my next button.
I was thinking if you can detect the first empty row or the last row of the database and if so hide the next button. Otherwise it keeps adding 30 to $startrow when nothing is shown on screen.
I found a script helping me with this here but it didn't tell me how to hide the next button.
<?php
$startrow = $_GET['startrow'];
if (!isset($_GET['startrow']) or !is_numeric($_GET['startrow'])) {
$startrow = 0;
} else {
$startrow = (int)$_GET['startrow'];
}
?>
<?php
$db = mysqli_connect("localhost", "root", "", "media");
$uploaded = mysqli_query($db, "SELECT * FROM images LIMIT $startrow, 30");
while ($row = mysqli_fetch_array($uploaded)) {
echo "<div class='img_container'>";
echo "<li><img class='img_box' src='uploads/images/".$row['image_title']."' ></li>";
echo "</div>";
}
$prev = $startrow - 30;
if ($prev >= 0) {
echo '<div class="prevRow">Back</div>';
}
echo '<div class="nextRow">Next</div>';
?>
You could try something like
$num_rows = 30; // rows on a page
$db = mysqli_connect("localhost", "root", "", "media");
// get total possible rows
$res = mysqli_query($db, "SELECT count(id) FROM images");
$row = $res->fetch_row();
$total_rows = $row[0];
$res->close();
$uploaded = mysqli_query($db, "SELECT * FROM images LIMIT $startrow, $num_rows");
while ($row = mysqli_fetch_array($uploaded)) {
. . .
}
$prev = $startrow - $num_rows;
if ($prev >= 0) {
echo '<div class="prevRow">Back</div>';
}
if ( $startrow+$num_rows < $total_rows ) {
echo '<div class="nextRow">Next</div>';
}
Potentially a little faster than the answer from #RiggsFolly, you can modify your existing query to count the rows.
SELECT SQL_CALC_FOUND ROWS * FROM images LIMIT $startrow, 30
Then, after the query returns, you run a second query to get the answer:
SELECT FOUND_ROWS()
The FOUND_ROWS() function returns the number of rows the previous query would have returned, without LIMIT (or an offset).
This is probably not as fast as your original query would be in isolation, but should be slightly faster than SELECT COUNT(...) ... followed by your original query. With small data sets, though, any differences will likely be below measurable limits.
See also https://dev.mysql.com/doc/refman/5.7/en/information-functions.html
You can also combine these things into a stored procedure that accepts items per page and page number, and returns all of the records along with metadata items such as the total number of pages.
$st = $this->db->prepare("SELECT * FROM invoices WHERE group_id=?");
$st->execute(array($id));
if($st->rowCount() >= 1){
foreach ($st as $row) {
$counter = $row["paymentAmount"];
$start = 1;
for($start; $start < $st->rowCount(); $start++) {
$counter = $counter + $row["paymentAmount"];
}
}
It actually print out $row["paymentAmount"] + $row["paymentAmount"] and so on, depending on how many $row["paymentAmount"] there is. But the problem is that the last output from $row["paymentAmount"] is 2500.
There is:
10000
10000
2500
And the result is: 7500
I want it to be: 22500
And if the last result is 3000 it shall be 23000. So what I simply need is this code to take every row from the database, just not the latest one.
Edit: I want it outside of the SQL query
You don't need PHP logic for something like this. The functionality is built right into SQL.
SELECT SUM(paymentAmount) FROM invoices WHERE group_id=?
You should let your database handle the sum unless you have a legitimate reason why it needs to be handled in PHP. The database is more efficient with this type of operation and you avoid a loop in PHP.
SELECT SUM(paymentAmount) AS TotalPaymentAmount FROM invoices WHERE group_id = ?
You can then change your PHP to return just one row:
$row = $st->fetch();
echo $row["TotalPaymentAmount"];
If you need to do this calculation outside of SQL, just change your loop:
if($st->rowCount() >= 1){
//init the counter to 0 before you loop through your rows
$counter = 0;
//the foreach will iterate over your result set and add the paymentAmount to $counter.
foreach ($st as $row) {
$counter += $row["paymentAmount"];
}
//echo results outside of the loop
echo $counter;
}
If you need to code this outside SQL on purpose (e.g. because you need to do further processing for each row), then I'd code this as follows:
if ($st->rowCount() >= 1) {
$counter = 0;
foreach ($st as $row) {
$counter += $row["paymentAmount"];
}
}
I am running a while loop in PHP selecting data from a mysql database. How can i find out what the last record is,
for example:
$sql="SELECT * from table1 ";
$rs=mysql_query($sql,$conn);
while($result=mysql_fetch_array($rs))
{
echo $result["col1"].' - '.$result["col2"].'<br>';
}
then when it gets to the last record i want to display it like:
echo 'Last Record: '.$result["col1"].' - '.$result["col2"].'<br>';
You basically need to record how many rows you have, and then set up a counter. You can do that using mysql_num_rows():
$sql="SELECT * from table1";
$rs = mysql_query($sql,$conn);
$numRows = mysql_num_rows($rs);
$i = 1;
while($result=mysql_fetch_array($rs))
{
echo ($i == $numRows) ? 'Last Record: '.$result["col1"].' - '.$result["col2"].'<br />' : $result["col1"].' - '.$result["col2"].'<br />';
$i++;
}
You should note though that the mysql_*() family of functions is now deprecated. For security and longevity, you really ought to be using MySQLi or PDO.
Get the total count of rows returned and check use a flag variable for the loop iterations and check in loop if flag == total rows
$t=mysql_num_row($rs);
$i=0;
while($result=mysql_fetch_array($rs))
{
$i++;
if($t == $i){
echo "Last Record ";
}
echo $result["col1"].' - '.$result["col2"].'<br>';
}
mysql_num_rows
You can simply use the sql query itself to get the last value, based on whatever ordering you want (or just use DESC to get the bottom of the natural order):
SELECT * FROM table1
ORDER BY your_column DESC
LIMIT 1;
Edit: Since you're looking for the last row, you could check with mysql_num_rows
$numrows = mysql_num_rows($rs);
$i = 1;
// in while loop...
if ($i === $numrows) {
// print last result
} else {
// print normal result
}
$i++;
// end while loop
Essentially, you want a counter for the record you are on and then write when the number of rows is the same as the row number you are on (e.g. the last one)
$sql="SELECT * from table1 ";
$rs=mysql_query($sql,$conn);
$num_rows = mysql_num_rows ($rs);
for ($i=0; $i < $num_rows; $i++) {
$result=mysql_fetch_array($rs);
if ($i == ($num_rows - 1)) {
echo 'Last Record: '.$result["col1"].' - '.$result["col2"].'<br>';
} else {
echo $result["col1"].' - '.$result["col2"].'<br>';
}
}
Future-proof this routine by doing it the "hard way":
while ($next_row = fetch_row(...)) {
if ($prev_row) { do_output($prev_row); }
$prev_row = $next_row;
}
if ($prev_row) { do_output($prev_row, FLAG_IS_LAST_ROW); }
Why? Future maintenance might make mysql_num_rows() unreliable, either because your result set gets too big, or because you want to interface with a variety of SQL backends.
By default, the MySQL client library pulls the entire result set into memory — that is how it knows the number of rows SELECTed without having to count fetches. This behavior is rather convenient for small result sets, but devastating for large result sets. This it is user-configurable. (The options are usually named something like "store_result v. use_result" or "buffered v. unbuffered.")
Additionally, most RDBMS interfaces do not make the size of the result set known in advance. If you want to interface with these some day in a reusable way, you'll need to change your approach.
Hi I'm currently querying from a database base user ids for a contest, However I want to avoid choosing duplicates in my results_array, this function getrandomspecies receives a array_result, this array results iterates 7 times. How test that I don't put duplicates in my results_array? I have gotten several duplicates.
function getrandomspecies($array_result){
//database connection
$dbn = adodbConnect();
foreach($array_result as $possible){
//query the results
$querys= "select * from taxonomic_units where tsn = $possible";
$resultss = $dbn -> Execute($querys);
while($rowss=$resultss->FetchRow()){
$id = $rowss['tsn']; //there ID
$ranksss = $rowss['rank_id']; //ranking id, I choose 220 and 230
if($ranksss == 220 || $ranksss == 230){
$prelimary_array[] = $id;
}
}
//grab random index
$index = array_rand($prelimary_array,1);
//put result id into a variable
$newspecies = $prelimary_array[$index];
//put that variable in an array
$results_array[] = $newspecies; //there is 7 newspecies/winners at the end, I dont want duplicates
}
return $results_array;
}
MySQL should be the following :
select distinct tsn, rank_id from taxonomic_units where tsn = $possible
But you should ideally use prepared statements.
what about this? You may do it with one query:
$querys= "select DISTINCT tsn from taxonomic_units where tsn IN (".implode(",",$array_result).") AND rank_id IN (220,230) ORDER BY RAND() LIMIT 7 ";
Loop your result array and if it does not exists add it. If you end up with less than 7, do your big loop again.
replace this line :
$results_array[] = $newspecies;
by:
$loop_1_more_time=0;
if (isset($results_array)){
foreach($results_array as $result){
if ($result == $new_specie){
$loop_1_more_time=1;
}
}
}
if ($loop_1_more_time == 0){
$results_array[] = $newspecies;
}
//there, if $loop_1_more_time equals 1, start again. To start again and be sure you have seven instead of 6 or less, You could replace your big first "foreach" loop with a "for" loop that depends of the count() of the $array_result, and the $array_result would be array_result[$i] instead of $possible. $i would start at 0 and increment at each end of loop. It would not be incremented if $loop_1_more_time==1;.
Example :
for ($i = 0; $i < count($array_result); $i++) {
//stuff
//if ($loop_1_more_time=1;) { $i--; }
}
Why don't you try shuffling the array, and then picking the first X numbers?
That way, rather than having to check the results array for duplicates, it will never come up in the first place
I am trying to create a class registration system for a client that utilizes PHP and MySQL. I have the database and table all set up and that part works just fine, however, the client has requested that upon registration, if there are 3 or fewer students enrolled to warn that the class may not run.
I'm trying to use the count() function as well as passing a dynamic variable from a cookie, set from the registration PHP script. However, I've hit a roadblock. I can't seem to get the count() function to actually count the rows. My select statement is below. Any help would be greatly appreciated.
$class = $_COOKIE["class"];
$min_check = "SELECT class_list, COUNT(class_list) as count
FROM T_Student WHERE class_list = '$class'
GROUP BY class_list
HAVING count < 20";
$result = mysql_query($min_check);
$count = mysql_num_rows($result);
if ($count < 4)
{
echo "IF THERE ARE 3 OR FEWER PEOPLE SIGNED UP FOR THIS CLASS, IT MAY NOT RUN.\n";
echo "THERE ARE CURRENTLY " . $count . " PEOPLE SIGNED UP.\n";
}
else if ($count > 4)
{
echo "There are currently " . $count . " people signed up for this class.";
}
?>
Your SQL query is returning a list of the class_list values, along with a count of each specific instance, where there are less than 20 people registered.
$count = mysql_num_rows($result);
...is getting the number of records returned in the resultset, not the alias count value, which is why you aren't seeing the output you expect. You need to read into your resultset to get the value:
while ($row = mysql_fetch_assoc($result)) {
$count = $row['count'];
if($count < 4) { ... }
}
The count that you want is returned in the row of the query. the mysql_num_rows will count the rows returned, which is not what you want. Use this instead.
$result = mysql_query($min_check);
$count = mysql_fetch_row($result);
$count = $count[0];
On a first glance, the HAVING count < 20 is unnecessary.
You use the MySQL-count-function, but never retrieve it's value!? Use:
$firstRow = mysql_fetch_row($result);
$count = $firstRow[1]; // 1 indicates the second column (0 being the first)
I don't recommend using known MySQL identifiers like count. It's confusing.
$class = mysql_real_escape_string($_COOKIE["class"]);
$min_check = "SELECT class_list, COUNT(class_list) as mycount
FROM T_Student WHERE class_list = '$class'
GROUP BY class_list
HAVING mycount < 20";
Don't forget to escape the contents of that cookie!
The error is that count is a reserved word. You need to either surround it in backticks `count` or even better, use a different moniker. It's not an error per se, but it's just too confusing.
Next up, you are not actually retrieving the mycount result from the database. I suggest using code something like this:
$result = mysql_query($min_check);
while( $row = mysql_fetch_assoc($result) ) {
$people_count = $row['mycount'];
if ($people_count < 4) { echo "this" }
else { echo "that" }
}