i have a mysql Table with some rows.
The Select gets one (LIMIT 1) row. After a counter it reloads and get random another row. But sometimes he get the same (cause random).
How can i setup that he dont get the last row?
The problem is, i cannot do that in mysql. I must do that in the SESSION or only on that site.
I tried that:
$_SESSION['ads'] .= ','.$adid;
put that adid in "ads" SESSION and read it before SELECT here
session_start();
$ads = substr($_SESSION['ads'], 1);
$ads = str_replace(",", "','", $_SESSION['ads']);
In the SELECT is that
AND id NOT IN ('".$ads."')
But sometimes, i dont know why, he save two items or something... i dont find out why, cause the SELECT is LIMIT 1
Any ideas how to do that or is there a mysql function?
For any reason, the script is load two times the SELECT or something
This is the code:
$query = "SELECT * FROM ads ORDER BY RAND() LIMIT 1;";
while($row = $result->fetch_assoc()) {
$adid = $row["id"];
$_SESSION['ads'][] = $adid;
}
echo 'adid: '. $adid;
print_r($_SESSION['ads']);
There he print like that:
Array
(
[0] => 6
[1] => 3
)
I dont know, why he puts 2 in there. Cause the echo of the $adid shows only one!
Try something like this maybe :
1/ Create a new session and create an empty array :
session_start();
if (empty($_SESSION['ads']))
$_SESSION['ads'] = array();
2/ Do you select and add the id in this array :
if (empty($_SESSION['ads']) {
// 1. Do your select with no where condition
// 2. Fetch the result
$data = /* result of the select */;
// 3. Add the selected id in your session array
$_SESSION['ads'][] = $data['id'];
} else {
// 1. Do your select but with a WHERE condition
$query = "SELECT...
WHERE id NOT IN ( " . implode( "', '" , $_SESSION['ads'] ) . " )";
// 2. Fetch the result
$data = /* result of the select */;
// 3. Add the selected id in your session array
$_SESSION['ads'][] = $data['id'];
}
Is it what you are looking for?
Related
From mysqli request I receive a result that contains a table with 5 columns and a number of rows. I would like to perform a calculation with my data that I just received and add the result of my calc in a NEW COLUMN in my array.
So in different words, I would like to add one column to the array and fill this column with results for each row.
My code so far looks as follows and of course only prints the array that I receive from my SQL query:
<?php
error_reporting(0);
require 'init1.php';
if($result = $db->query("Select * from (select * from(SELECT * FROM `scores`
ORDER BY `battle_id` ASC,user_id asc,score desc) as t1 GROUP BY
t1.battle_id, t1.user_id) as t2 order by `battle_id` ASC,score desc")){
if($count = $result->num_rows){
echo '<p>' , $count, '<p>';
while ($row = $result->fetch_object()){
echo $row->battle_id, ' ' , $row->user_id, ' ' , $row->score, '<br>';
}
//instead of just printing the existing array, I would like to perform a
//calculation and add a result in a new column at the end of every single
//row
}
}
If you use an Array you can simply 'define' a new item in your array to store the calculation result.
while ($row = $result->fetch_row()) {
// Calculation and other stuff here
$row['calc_result'] = $calculation_result;
}
Then in order to access it outside the while scope, you would need to store each row in another array, for example:
$stored_data = array();
while ($row = $result->fetch_row()) {
// Calculation and other stuff here
$row['calc_result'] = $calculation_result;
array_push( $stored_data, $row );
}
I have an array like below and that array refers to another data on my db,
Array
(
[0] => 4
[1] => 1
[2] => 15
[3] => 1
[4] => 1
)
how do I want to select value no 1, and get the most top value from table that has value=1?
I use in_array(1,$array) but it does not output anything. Below are my coding;
$sql = " Select * FROM table_name WHERE staff_id='".$_SESSION['staff_id']."' ORDER BY table_name DESC ";
$result=mysqli_query($conn,$sql) or die(mysqli_error());
$leave_id= array();
while($row_permohonan=mysqli_fetch_assoc($result_permohonan))
{
$leave_available = $row_permohonan['leave'];
$leave_id[] = $row_permohonan['leave_id'];
} mysqli_free_result($result_permohonan);
//echo '<pre>'; print_r($leave_id); echo '</pre>';
if(in_array(1,$leave_id)){
echo $leave_available .'/'.$row['total_leave'];
}
I think you have missed $result.
$sql = " Select * FROM table_name WHERE staff_id='".$_SESSION['staff_id']."' ORDER BY table_name DESC ";
$result=mysqli_query($conn,$sql) or die(mysqli_error());
$leave_id= array();
while($row_permohonan=mysqli_fetch_assoc($result)) //Here
{
$leave_available = $row_permohonan['leave'];
$leave_id[] = $row_permohonan['leave_id'];
} mysqli_free_result($result); //And here
First, your code is not clear. You are using:
echo $leave_available.'/'.$row['total_leave'];
Where "$row" is not set anywhere into your code. If you have put on top of your code:
ini_set("display_errors", "On"); error_reporting(E_ALL);
PHP would break with a fatal error if you are executing the code exactly as you gave it. But I assume that you set it somewhere else into your code.
2nd: You should return the data you want into your MySQL query. If you just want to know if there is at least 1 row into your database having leave_id=1 and staff_id=$_SESSION['staff_id'], then add this condition in your SQL query:
$sql = "Select COUNT(*) AS nbrows FROM table_name WHERE staff_id='".$_SESSION['staff_id']."' AND leave_id=1 ORDER BY column_name DESC ";
And then: you have to use "ORDER BY" statement with a column name and not the table name.
Using "in_array": as you are matching "1", I would recommend you to add "true" as 3rd parameter of this function (force using "strict comparison" in case sensitive and type matching):
in_array(1, $array, true)
Then, you'll also have to cast your $leave_id result:
$leave_id[] = (int)...
(int) cast the string value to integer (as PHP results from database are almost strings)
I need to create loop, get lowest ID value from mysql.
So I tried this script:
<?php
include "configuration.php"; // mysql konfiguration
$jungiam = mysql_connect("$db_host", "$db_user", "$db_pass");
mysql_select_db($db_name, $jungiam);
$darom = mysql_query("SELECT * from task where id = (
SELECT
MIN(id)
FROM
task)");
$rez = mysql_num_rows($darom);
while ($rez > 1) {
$row = mysql_fetch_array($darom);
echo $komanda = $row['komanda'];
mysql_query('DELETE * FROM task WHERE komanda = ' .$row['komanda'].'');
}
return true;
?>
I need to get lowest id and print to page $row['komanda'], after printing delete from that table where komanda = $row['komanda'] (printed text).
After deleting record, I need to do script from the start, so it will print text with lowest id from mysql and after that text will be deleted and proccess will start from start and will be repeating until all records in table 'task' will be deleted.
"SELECT * from task ORDER BY id ASC LIMIT 1;"
This will return the first element with the lowest ID.
I was just hoping someone could help me speed up 4 queries with a multi query.
GOAL: a single multi query to function as the single queries below.
Simple queries, i am checking one table to see if user is banned, then if not, i am getting row for the id and updating it's view count by 1. If user is banned, i do not want the last to queries to complete.
Thank you in advance for your help.
current performance is around 1200ms. (+1000ms avg for facebook graph api query).
NOTE: af_freefeed.pageid & af_ban.pageid are both indexed in database.
ALSO: I have been studying and referencing from http://www.php.net/manual/en/mysqli.multi-query.php i just can not see how to get this config into multi with the if()
$fconn = new mysqli($fdbhost, $fdbuser, $fdbpass, $fdbname) or die ('Error connecting to mysqli');
// 12,000 rows for af_ban - bigint(255) : indexed
$q = sprintf('SELECT COUNT(pageid) AS numrowst FROM af_ban WHERE pageid = %s', $banpage);
$readtop = $fconn->query($q);
$rowtop = $readtop->fetch_assoc();
// 1.17 million rows for af_freefeed - bigint(255) : indexed
if($rowtop[numrowst] == 0){
$q = sprintf('SELECT COUNT(pageid) AS numrowsf FROM af_freefeed WHERE pageid = %s', $banpage);
$readf = $fconn->query($q);
$rowf = $readf->fetch_assoc();
// increment views
$read = $fconn->query("Update af_freefeed SET views = views + 1 WHERE pageid = ".$banpage."");
}
$q=$fconn->query("SELECT pagename,views,pageid FROM af_freefeed ORDER BY views DESC LIMIT 0, 20");
unset($q);
unset($rowf);
unset($rowtop);
mysqli_close($fconn);
actual request times.
grah api: 1127.04610825ms.
conncect: 1.20711326599ms.
check banned: 0.405788421631ms.
get row: 418.189229965ms.
increment views: 472.24655151ms.
get top20: 94.31447983ms.
Multi_query #1 How to stop the multi query if user is banned?
Possible Contender: 943.8181ms. if added : 933.1279ms. if banned
10ms difference if exit loop for banned. This leads me to believe the loop is completing all the queries before they are actually supposed to be executed, "next_result". Or i have an error in how i looped the functions.
replaced exit; with $thread_id = $fconn->thread_id; $fconn->kill($thread_id);
if banned 953.4719ms. no gain.
$banpage='234232874008';
$query = "SELECT pagename,views,pageid FROM af_freefeed ORDER BY views DESC LIMIT 0, 2;";
$query .= "SELECT pageid AS isbanned FROM af_ban WHERE pageid = \"".$banpage."\";";
$query .= "SELECT pageid AS isadded FROM af_freefeed WHERE pageid = \"".$banpage."\";";
$query .= "Update af_freefeed SET views = views + 1 WHERE pageid = \"".$banpage."\"";
/* execute multi query */
if ($fconn->multi_query($query)) {
if ($result = $fconn->store_result()) {
while ($row = $result->fetch_row()) {
print_r($row).'<br />';
}
$result->free();
}
if ($fconn->more_results()) {
while ($fconn->next_result()){
if($thisresult = $fconn->store_result()){
while (is_array($row = $thisresult->fetch_array())) {
if(isset($row['isbanned'])){
if($row['isbanned']===''.$banpage.''){
$thread_id = $fconn->thread_id;
$fconn->kill($thread_id);
// exit;
}
}
}
}
}
}
}
unset($query);
unset($result);
unset($thisresult);
Multi_query #2 "current for benchmark" How to remove duplicate fields in result set after next_result()?
2.667ms. / 1032.2499ms. but print_r is showing duplicate fields in $thisresults?
**Array
(
[0] => 37
[id] => 37
[1] => 159616034235
[pageid] => 159616034235
[2] =>
[userid] =>
[3] => 30343
[views] => 30343
[4] => Walmart
[pagename] => Walmart
)**
$query = "SELECT pageid AS isbanned FROM af_ban WHERE pageid = \"".$banpage."\";";
$query .= "SELECT pageid AS isadded FROM af_freefeed WHERE pageid = \"".$banpage."\";";
$query .= "SELECT * FROM af_freefeed ORDER BY views DESC LIMIT 0, 20";
//$query .= "Update af_freefeed SET views = views + 1 WHERE pageid = \"".$banpage."\"";
/* execute multi query */
echo '<pre>';
$i=0;
if ($fconn->multi_query($query)) {
if ($result = $fconn->store_result()) {
//$row = $result->fetch_assoc();
while ($row = $result->fetch_assoc()) {
print_r($row).'<br />';
}
$result->free();
}
if ($fconn->more_results()) {
while ($fconn->next_result()){
if($thisresult = $fconn->store_result()){
while ($row2 = $thisresult->fetch_array()) {
if(isset($row2['isadded'])){
if($row2['isadded']===''.$banpage.''){
$addone = $fconn->query("Update af_freefeed SET views = views + 1 WHERE pageid = ".$banpage."");
}
}
print_r($row2);
}
}
}
}
}
/* determine our thread id */
$thread_id = $fconn->thread_id;
/* Kill connection */
$fconn->kill($thread_id);
//
echo '</pre><hr/>';
Try to use index in getting count. Like for example COUNT(pageid). It will speed up your query.
Update
You can also try this link for further explanation
EDIT : So now, the conclusion: (test case below)
You cannot control the execution of subsequent statements of a multi-statement query.
You can therefore not use multi_query() in the way you wanted to.
Execute them all, or execute none.
Regarding
Multi_query #2 "current for benchmark" How to remove duplicate fields in result set after next_result()?
Use fetch_assoc() or fetch_array(MYSQLI_ASSOC) (both practically the same) instead of fetch_array().
About multi_query():
I recently worked on a program using the MySQL C API, which mysqli uses, too.
About multiple-statement query support the documentation states:
Executing a multiple-statement string can produce multiple result sets or row-count indicators. Processing these results involves a different approach than for the single-statement case: After handling the result from the first statement, it is necessary to check whether more results exist and process them in turn if so. To support multiple-result processing, the C API includes the mysql_more_results() and mysql_next_result() functions. These functions are used at the end of a loop that iterates as long as more results are available. Failure to process the result this way may result in a dropped connection to the server.
(emphasize added)
This leads to the conclusion, that aborting a multiple-statement query is not an intended feature.
Moreover, I didn't find any resource explaining when subsequent queries are actually executed.
Calling next_result() doesn't neccessarily mean that the query hasn't been executed already.
EDIT : TEST CASE
To prove what I previously assumed, I created a test case:
<?php
$db = new mysqli('localhost', 'root', '', 'common');
$query = 'SELECT NOW() as time;';
$query .= 'SELECT NOW() as time;';
$query .= 'SELECT NOW() as time;';
$query .= 'SELECT NOW() as time;';
if($db->multi_query($query)) {
// Current time
echo "'multi_query()' executed at:\n\t\t"
.date('Y-m-d H:i:s')."\n";
// First result
if($result = $db->store_result()) {
$i = 1;
$row = $result->fetch_assoc();
echo "'NOW()' of result $i:\n\t\t".$row['time']."\n";
$result->free();
// Wait 5 seconds
sleep(5);
// Subsequent results
while($db->more_results() && $db->next_result()) {
$result = $db->store_result();
$row = $result->fetch_assoc();
$i++;
echo "'NOW()' of result $i:\n\t\t".$row['time']."\n";
// Wait 5 seconds
sleep(5);
$result->free();
}
}
}
$db->close();
?>
This results in:
'multi_query()' executed at:
2013-05-10 10:18:47
'NOW()' of result 1:
2013-05-10 10:18:47
'NOW()' of result 2:
2013-05-10 10:18:47
'NOW()' of result 3:
2013-05-10 10:18:47
'NOW()' of result 4:
2013-05-10 10:18:47
Given that, it is obvious that all four statements of the query were executed directly after the call to multi_query().
If they were only executed after calling next_result() there would be a 5 second delay caused by sleep(5) calls I added between the loop iterations.
Please run following query in mysql and check your query run time :
CREATE INDEX pagidIndex ON af_ban (pageid(11));
CREATE INDEX pagidFeedIndex ON af_freefeed (pageid(11));
CREATE INDEX viewsIndex ON af_freefeed (views(11));
i am checking one table to see if user is banned, then if not, i am getting row for the id and updating it's view count by 1.
The following query may help you to update the view count. I assume that you already know the page_id.
UPDATE af_freefeed SET views=views+1 WHERE page_id=%s and page_id not in (select page_id from af_ban WHERE page_id=%s);
You could try something along these lines:
$sql = sprintf("SELECT af_freefeed.pageid FROM af_freefeed left join af_ban ".
"on (af_freefeed.pageid = af_ban.pageid) ".
"where af_freefeed.pageid = %s and ".
"af_ban.pageid is null limit 1", $pageid);
to replace your first two queries.
The existence of a record in the results should indicate an unbanned user requesting the resource. Then you can do your update your views.
Hope this helps.
I have a table containing 4 articles with id 1,2,3 and 4 as well as ordering value 1,2,3,4.
They have separate columns for their title, image etc. I need to get them distinctly with where clause. So i did:
For article 1:
//topstory1
$sql_topstory1 ="SELECT * FROM topstory WHERE story_active='1' && story_order='1'";
$result_topstory1 = mysql_query($sql_topstory1);
$row_topstory1 = mysql_fetch_array($result_topstory1);
$story1_title = $row_topstory1['story_title'];
$story1_abstract = $row_topstory1['story_text'];
And for article 2
//topstory2
$sql_topstory2 ="SELECT * FROM topstory WHERE story_active='1' && story_order='2'";
$result_topstory2 = mysql_query($sql_topstory2);
$row_topstory2 = mysql_fetch_array($result_topstory2);
$story2_title = $row_topstory2['story_title'];
$story2_abstract = $row_topstory2['story_text'];
As I have to reuse them in a page.
PROBLEM IS, the first query works but the second one doesn't. It seems like MySql cannot execute two consecutive queries on the same table in a single php file. But I think there is a simple solution to this...
Please help me soon :( Love you guys :)
There are several possible reasons for the second query to fail, but the fact that it's the second query in the file does not cause it to fail.
I would expect that article 2 does not have the active flag set to 1, causing you to get an empty result set.
Another option is that you may have closed the mysql connection after the first query, then you can't execute another query. (General rule: don't close database connections. PHP takes care of that.)
Why not just get them both with 1 query?
$sql_topstory ="SELECT * FROM topstory WHERE story_active='1' && story_order IN(1, 2) ORDER BY story_order DESC";
$result_topstory = mysql_query($sql_topstory) or trigger_error('Query Failed: ' . mysql_error());
while ($row = mysql_fetch_assoc($result_topstory)) {
$title[] = $row['story_title'];
$abstract[] = $row['story_abstract'];
}
// Then to display
echo 'Story 1 is ' . $title[0] . ' with an abstract of ' . $abstract[1];
There are plenty of ways to do this, this is just a simple demonstration.
$query = <<<SQL
SELECT
story_title
, story_text
FROM
topstory
WHERE
story_active
ORDER BY
story_order ASC
SQL;
$result = mysql_query($query);
$stories = array();
while ($row = mysql_fetch_assoc($result)) {
$stories[] = $row;
}
Now you have an array of stories like so:
array(
0 => array(
'story_title' => ?
, 'story_text' => ?
)
, 1 => array(
'story_title' => ?
, 'story_text' => ?
)
)
Should be pretty easy to iterate through.