I have the following query:
$trabajos = $con->query("SELECT * FROM portafolio ORDER BY RAND() LIMIT 4");
while ($po = $trabajos->fetch_array()) {
$trab[] = $po;
}
This query is working fine, but, it shows only 4 records, but then again in another part of the same page I need the same table information but I don't want it to be limited, say I want 10 instead of only 4. so.
Section Header
Section Slider <-- here only shows 4 items as intended
Using a foreach as follow:
foreach ($trab as $it) {
// My html Code
}
Section Mid Body some info
Section Main Body More info
Section Mid End Footer <-- here I need the same information as in the slider section but with a different layout instead of only 4 items I need 10 items.
For that last item I have to open another query similar as before.
$trabajos = $con->query("SELECT * FROM portafolio ORDER BY RAND() LIMIT 10");
while ($po = $trabajos->fetch_array()) {
$trab[] = $po;
}
So I was thinking is there a way to use:
$trabajos = $con->query("SELECT * FROM portafolio ORDER BY RAND()");
while ($po = $trabajos->fetch_array()) {
$trab[] = $po;
}
That query without the LIMIT and instead Limit the foreach to only fetch the first 4 rows or is there a way to use that query with the LIMIT but instead of 4 or 10, say I use 20, and for the first foreach only display the first 4 and for the second foreach show the rest after the first 4.
The main idea is not have more than 1 query for the same information.
this will exit a loop, but why not query 10 records, build your results, all 10 and then just output 4 of them, there and all 10 over yonder.
$x = 0;
foreach ($trab as $it) {
if($x == 5){
break; //will exit loop as will return.
}
// My html Code
++$x;
}
This will work with any kind of loop, you can also use continue to skip to the next pass of the loop
foreach ($trab as $it) {
if($x < 5){
continue; //code below here wont run until $x >= 5.
}
// My html Code
++$x;
}
i'm not sure to understand exactly what you want, but if you want to divide your array in 2 part. You can use a counter
$trabajos = $con->query("SELECT * FROM portafolio ORDER BY RAND() LIMIT 20");
$i = 0;
$trab2 = new Array();
while ($po = $trabajos->fetch_array()) {
if($i < 4) {
$trab[] = $po;
} else {
$trab2[] = $po;
}
$i++;
}
First, RAND() is horrible since it essentially disables MySQL’s built in caching with each run of the query. But there is no best way for me to advise how to get around that based on your script’s requirements. So just keep that in mind. But here is what I would recommend.
That query without the LIMIT and instead Limit the foreach to only
fetch the first 4 rows or is there a way to use that query with the
LIMIT but instead of 4 or 10, say I use 20, and for the first
foreach only display the first 4 and for the second foreach show
the rest after the first 4.
Yes, just use array_slice like this:
$trabajos = $con->query("SELECT * FROM portafolio ORDER BY RAND() LIMIT 20");
while ($po = $trabajos->fetch_array()) {
$trab[] = $po;
}
$trab_slice_1_size = 4;
$trab_slice_2_size = 10;
$trab_slice_1 = array_slice($trab, 0, $trab_slice_1_size);
$trab_slice_2 = array_slice($trab, $trab_slice_1_size, $trab_slice_2_size);
The nice thing about array_slice is you can cleanly select a start & end point. In my example I set the sizes in variables. Which makes it easier to adjust in your code if you somehow want to dynamically change values.
The easiest way is to use a counter variable:
function fetch_items($limit=10) {
public $trabajos,$trab;
$count=0;
$trabajos = $con->query("SELECT * FROM portafolio ORDER BY RAND()");
while (($po = $trabajos->fetch_array()) && ($count<$limit)) {
$count++;
$trab[] = $po;
}
}
If you call fetch_items() without a parameter, it defaults to 10 or less. If you specify a parameter it loads the array with up to the amount you specify. You could also have the function return the value of $count so you know how many were returned.
try;
$trabajos = $con->query("SELECT * FROM portafolio ORDER BY RAND() LIMIT 10");
$i = 0;
while ($i < 5 && $po = $trabajos->fetch_array()) {
.....
.....
$i++;
}
then, if you want to re-use the data,
mysql_data_seek($trabajos, 0);
$i = 0;
while ($i < 11 && $po = $trabajos->fetch_array()) {
.....
.....
$i++;
}
Related
I am making Tournament mod. And I do not know how to correctly do some operations with fetched array.
What my code is doing, is that it takes data from Tournament table and add it to array. Then print it in HTML table, so all users can see the place where he has.
How can I correctly get the first, second, third array data for the first 3 winners and give them a price? And how can I deal with players who have the same amount of points?
Right now the query below seems to not work too, all statements are positiv and it should execute the function.
if($counter == 1) {
$GLOBALS['DATABASE']->query("UPDATE ".USERS." SET `atm` = `atm` + 20000 WHERE `id` = ".$recordRow['id_owner']." ;");
}
Sorry, my English is not good and I tried to search for the answers but didn't find anything, because i do not know for what PHP solution should i search.
My code:
$recordFetch = $GLOBALS['DATABASE']->query("SELECT *FROM `uni1_tournament` ORDER BY wons DESC;");
$counter = 0;
$RangeList = array();
while ($recordRow = $GLOBALS['DATABASE']->fetch_array($recordFetch)) {
$counter += 1;
$RangeList[] = array(
'id' => $recordRow['id_owner'],
'name' => $recordRow['name'],
'points' => $recordRow['wons']*5,
'counter' => $counter,
);
if($t_time > TIMESTAMP) {
if($counter == 1) {
$GLOBALS['DATABASE']->query("UPDATE ".USERS." SET `atm` = `atm` + 20000 WHERE `id` = ".$recordRow['id_owner']." ;");
}
elseif($counter == 2) {
//to do;
} elseif($counter == 3) {
//to do;
}
}
}
Make query like this "select * from uni1_tournament GROUP BY points ORDER BY
points desc limit 3";
If you're using regular mysql or mysqli (been a while since I have for either, moved to doctrine a while back), fetch_array needs to be ran on the results and not the GLOBALS['DATABASE'] variable (guessing this a global variable for the database connection).
Try changing
while ($recordRow = $GLOBALS['DATABASE']->fetch_array($recordFetch)) {
to
while ($recordRow = $recordFetch->fetch_array()) {
In order to use your original formatting, I believe fetch_array needed to be mysqli_fetch_array instead.
i.e
while ($recordRow = $GLOBALS['DATABASE']->mysqli_fetch_array($recordFetch)) {
$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"];
}
}
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
Can someone help me please? I am sure it is easy for you guys. I am battling to find a solution on how to hide the next link when there are no pages to display my code is as follows:
if (!isset($_GET['page']) or !is_numeric($_GET['page'])) {
$page = 0;
} else {
$page = (int)$_GET['page'];
}
$pages_query=mysql_query ("SELECT COUNT * FROM hardware");
$result = mysql_query("SELECT * FROM hardware LIMIT $page, 3");
echo 'Next<p>';
$prev = $page - 3;
//only print a "Previous" link if a "Next" was clicked
if ($prev >= 0) {
echo 'Previous';
}
You can use mysql_num_rows($result) to get the number of records in hardware:
$result = mysql_query("SELECT * FROM hardware LIMIT $page, 3");
$record_count = mysql_num_rows($result);
if ($record_count > 1)
echo 'Next';
in your if statement check if the $page is greater than 0 then according to the outcome of the value of $page write your code. you can use another if statement in the first if statement and make it detect the situation and decide what to do. The other thing is if the user clicked next then the user is on the second page so your previous should appear if $prev is higher than 1 it should make it
something along the lines of:
$itemsPerPage = 3;
$sql = "SELECT * FROM hardware";
$result = mysql_query($sql);
$count = mysql_num_rows($result);
$pageCount = $count/$itemsPerPage;
if($pageCount > $page) { //Are there more pages worth of items stored, than we're currently looking at?
echo 'next';
}
You want to be using OFFSET in your SQL syntax, as well as LIMIT.
LIMIT limits the number of rows returned.
OFFSET tells it to start a number of rows into the result set.
You need to limit to the number of items you want on a page. and offset by that number*page.
Hopes this helps.
Is it possible to create pagination without getting all elements of table?
But with pages in GET like /1 /666…
It usually involves issuing two queries: one to get your "slice" of the result set, and one to get the total number of records. From there, you can work out how many pages you have and build pagination accordingly.
A simply example:
<?php
$where = ""; // your WHERE clause would go in here
$batch = 10; // how many results to show at any one time
$page = (intval($_GET['page']) > 0) ? intval($_GET['page']) : 1;
$start = $page-1/$batch;
$pages = ceil($total/$batch);
$sql = "SELECT COUNT(*) AS total FROM tbl $where";
$res = mysql_query($sql);
$row = mysql_fetch_assoc($res);
$total = $row['total'];
// start pagination
$paging = '<p class="paging">Pages:';
for ($i=1; $i <= $pages; $i++) {
if ($i==$page) {
$paging.= sprintf(' <span class="current">%d</a>', $i);
} else {
$paging.= sprintf(' %1$d', $i);
}
}
$paging.= sprintf' (%d total; showing %d to %d)', $total, $start+1, min($total, $start+$batch));
And then to see your pagination links:
...
// loop over result set here
// render pagination links
echo $paging;
I hope this helps.
Yes, using mySQL's LIMIT clause. Most pagination tutorials make good examples of how to use it.
See these questions for further links and information:
How do you implement pagination in PHP?
Searching for advanced php/mysql pagination script
more results
You can use LIMIT to paginate over your result set.
SELECT * FROM comments WHERE post_id = 1 LIMIT 5, 10
where LIMIT 5 means 5 comments and 10 is the offset. You can also use the longer syntax:
... LIMIT 5 OFFSET 10