PHP / SQL give rest of users a value - php

What I did was to give 2 users in my DB a categorie_bit value of 1,
When I click on a button. That works so far. Now I am trying to give the rest of the user a categorie_bit value of 0, if I click on that button.
So basically:
Give 2 Random Users categorie_bit value 1 & Give Rest of the User in DB categorie_bit value of 0.
(Again giving 2 random Users value of 1 works and saves in db.)
I tried this so far to give the rest a value of 0:
$member = $staff->getStaffData($id);
$queryCheck = $database->query('SELECT id,firstname,lastname,categorie_bit FROM `staff` WHERE categorie_bit = 1');
$queryCheckResult = $queryCheck->fetch();
$queryMaximum = $queryCheckResult > 1;
var_dump($queryMaximum); // true
// MY SQL TO GIVE REST A VALUE OF 0
$taste = $database->query('SELECT id,firstname,lastname FROM `staff` WHERE categorie_bit = 1 SET categorie_bit = 0');
if($queryMaximum) {
echo "first step works";
if(is_array($taste) || is_object($taste)) {
echo "second step works";
foreach ($taste as $testx) {
var_dump($testx);
}
} else {
echo "second does not work";
}
}
This did not work. I always get the echo of second does not work.
Can anyone help me:)

The request you perform is wrong.
Either you make a select to retrieve user or you make an update to update user.
If you replace
'SELECT id,firstname,lastname FROM `staff` WHERE categorie_bit = 1 SET categorie_bit = 0'
With :
"UPDATE staff SET categorie_bit = 0 where categorie_bit = 1"
Your data should be updated ;)

you have used SET in SELECT statement which can be used in UPDATE query. Be specific on what you want to query from DB. If you want to update all records with category_bit = 0 then
$taste = $database->query('UPDATE `staff` SET categorie_bit = 0 where categorie_bit = 1');

Related

PHP / SQL: Update Table C if meet condition after updated in Table A and Table B

I got some issues with my current code. Example, on a PHP page, there's a table that displays all tools that borrowed the users. In that table, each data rows contain a checkbox. Users can select any tools that they want to return first by tick the checkbox and press "return" button.
At Server-side, after clicking the "return" button, it will go to the page named return_selected.php. At this page, it will update Table A and Table B. This one is successful.
Now, I want to update Table C if all there's a condition, for example, ALL tools returned. This one I still do but failed. Below is the code
return_selected.php
<?php
include("../../../../config/configPDO.php");
include("../../../../config/check.php");
$tools_id = $_POST['tools_id'];
$borrow_id = $_POST['borrow_id'];
$checkbox=explode( ',', $_POST['ids'][0] );
for($i=0;$i < count($checkbox); $i++){
$tools_id=$checkbox[$i];
$sql="UPDATE ets_tools SET borrow_id = NULL WHERE tools_id=:tools_id";
$query=$conn->prepare($sql);
$query->execute(array(':tools_id' => $tools_id));
$sql2="UPDATE ets_tools_borrow SET time_to = GETDATE() WHERE tools_id=:tools_id";
$query3=$conn->prepare($sql2);
$query3->execute(array(':tools_id' => $tools_id));
// want to update table if all tools returned.
$query2 = "
SELECT
ets_tools.tools_id, ets_tools.tools_name, ets_tools.borrow_id,
ets_borrow.time_from, ets_borrow.time_to, ets_borrow.status_id
FROM ets_tools
INNER JOIN ets_borrow ON ets_tools.borrow_id = ets_borrow.borrow_id
WHERE ets_tools.borrow_id IS NOT NULL AND ets_borrow.borrow_id = :borrow_id
";
$sql2=$conn->prepare($query2);
$sql2->execute(array(':borrow_id' => $borrow_id));
if($sql2->rowCount() > 0)
{
header("Location: return.php");
}else{
$sql3="UPDATE ets_borrow SET time_to = GETDATE(), status_id = 2 WHERE borrow_id=:borrow_id";
$query3=$conn->prepare($sql3);
$query3->execute(array(':borrow_id' => $borrow_id));
header("Location: return.php");
}
}
?>
Can anyone know how to solve this? Thank you.
You need to consider the following:
As is mentioned in the documentation, PDOStatement::rowCount() returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement executed by the corresponding PDOStatement object and for most databases the number of rows returned from a SELECT statement is not returned correctly. So, you may use a SELECT COUNT(*) ... approach to get this count.
For your specific case you may try to use an UPDATE ... WHERE NOT EXISTS ... statement to update the rows in the ets_borrow table and skip this SELECT ... FROM ... INNER JOIN ... statement.
I'm not sure if I understand corectly the use of header("Location: return.php"); in a for loop, probably you need to redirect after this loop.
Example, based on your code:
<?php
include("../../../../config/configPDO.php");
include("../../../../config/check.php");
$tools_id = $_POST['tools_id'];
$borrow_id = $_POST['borrow_id'];
$checkbox=explode( ',', $_POST['ids'][0] );
for($i=0; $i < count($checkbox); $i++) {
$tools_id=$checkbox[$i];
$sql = "UPDATE ets_tools SET borrow_id = NULL WHERE tools_id = :tools_id";
$query = $conn->prepare($sql);
$query->execute(array(':tools_id' => $tools_id));
$sql2 = "UPDATE ets_tools_borrow SET time_to = GETDATE() WHERE tools_id = :tools_id";
$query2 = $conn->prepare($sql2);
$query2->execute(array(':tools_id' => $tools_id));
$sql3 = "
UPDATE ets_borrow
SET time_to = GETDATE(), status_id = 2
WHERE
(borrow_id = :borrow_id1) AND
NOT EXISTS (
SELECT 1
FROM ets_tools
INNER JOIN ets_borrow ON ets_tools.borrow_id = ets_borrow.borrow_id
WHERE ets_tools.borrow_id IS NOT NULL AND ets_borrow.borrow_id = :borrow_id2
)
";
$borrow_id1 = $borrow_id;
$borrow_id2 = $borrow_id;
$query3 = $conn->prepare($sql3);
$query3->execute(array(':borrow_id1' => $borrow_id1, ':borrow_id2' => $borrow_id2));
}
header("Location: return.php");
?>

Retrieve id and handle it

I have the following table, named "question".
I want a query that will retrieve the maximum QID from the table where I specify a Pid. Then I want to take the selected value and add 1 to it. I want this to work even if there is no value where Pid is for example 1 or 2.
For example if the max qid is 1 where pid is 1, I want a code to retrieve a 1 and add 1. If I in my query put "WHERE pid=2" and there is no pid=2 in my table, I want it to make qid=1.
I have this code to get the maximum qid-value but it doesn't work.
$qu = mysqli_query("SELECT max(qid) AS id FROM answer_det WHERE WHERE pid = '1' ");
$result = $mysqli->query($qu);
if ($result->num_rows > 0) {
while($row = $result->fetch_array()) {
echo $row['id'];
}
}
I think you should use ifnull
$qu = mysqli_query("SELECT ifnull(max(qid)+1, 1) AS id
FROM answer_det WHERE WHERE pid = '1' ");
In this way if you try a query for a pid that not exist you get the value 1 otherwise you get the value +1

How to update top 5 enteries from the chosen top 10 enteries from db

WRT: how to insert records for top 10 enteries only
This is more refined question.
I have gathered top 10 users for specific task. Using the query given below.
mysql_query("SELECT `userid`, SUM(`points`) as `total` FROM
`tablename` GROUP BY `userid` ORDER BY total DESC LIMIT 10");
Now , I need to award bonues to the top 3 gathered users only, out of these selected top 10. I am not getting the idea , on how to write query for this purpose.
The top 3 bonuses are different for top 3
1: First user gets 1000 points
2: 2nd user gets 500 points
3: 3rd user gets 100 points
I need to update one field in tablename = user , field name = points.
To update the bonus i am using the below query(general query):
$Db1->query('UPDATE user SET points=points+'.$rate.'
WHERE userid = '.$credituser);
I hope this question is well elaborated as per the community standards.
Kindly guide.
Working on a pure MySQL version.
As you've PHP tagged, I'll incorporate that into my answer :)
(Ps: Don't use mysql_*. As OP used mysql_*, my answer will)
Fetch the results
Loop through the results
Update the results depending on their position
$objGet = mysql_query("SELECT `userid`, SUM(`points`) as `total` FROM
`tablename` GROUP BY `userid` ORDER BY total DESC LIMIT 10");
if( mysql_num_rows($objGet) ) {
$intIteration = 1;
while( $arrResults = mysql_fetch_assoc($objGet) ) {
switch($intIteration) {
case 1 :
mysql_query("UPDATE tablename SET points = points + 1000 WHERE userid = ". $arrResults['userid']);
break;
case 2 :
mysql_query("UPDATE tablename SET points = points + 500 WHERE userid = ". $arrResults['userid']);
break;
case 3 :
mysql_query("UPDATE tablename SET points = points + 100 WHERE userid = ". $arrResults['userid']);
break;
default:
//No idea.
//Not in the top 3.
break;
}
$intIteration++;
}
} else {
//No users.
}

Mysqli query performance multi-query

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.

PHP + 1 really adds two

Currently, I have the following PHP code loaded every time the page is refreshed. I am trying to update the views column +1 every time the page is loaded. To do this, I first retrive the previous views value from the table, then run another query to add + to that number. The problem that is occurring is every time I refresh the page, The code somehow adds two instead of 1. So instead of the $viewsA variable increasing by +1, it is increasing by +2.
$query = mysql_query("SELECT * FROM Games WHERE pagename = '$game' ");
WHILE($datarows = mysql_fetch_array($query)):
$title = $datarows['title'];
$description = $datarows['desc'];
$img_url = $datarows['img'];
$cat = $datarows['cat'];
$pagename = $datarows['page'];
$rating = $datarows['rat'];
$viewsA = $datarows['view_count'];
$gameid = $datarows['id'];
endwhile;
$updateviews = $viewsA +1;
mysql_query("UPDATE `trainw_games`.`Games` SET `view_count` = '$updateviews' WHERE `Games`.`id` = $gameid;");
What do I need to change to make it only add +1 to the views column?
I don't think that a while loop is appropriate for this problem. I would recommend to echo $viewsA . '-' . $updateviews; to see what the value is before and after the add.
But, why not just run a single UPDATE statement?
UPDATE Games SET view_count = view_count + 1 WHERE Games.id = $gameid
Of course, you should stop using mysql_ functions and use either MySQLi or PDO:
$stmt = $mysqli->prepare("UPDATE Games SET view_count = view_count + 1 WHERE Games.id = ?");
$stmt->bind_param($gameid);
$stmt->execute();
$stmt->close();
Do you have multiple rows in your database? If yes, it maybe caused by overriding the previous value.
For example:-
If first row the view_count is 1.
While the second row view_count is 2.
that overrides the the first row with 2 + 1 = 3
Which makes you thought increased by 2?
UPDATE 1:
Ok, try this, put this
$updateviews1 = $viewsA + 1;
if ($viewsA < $updateviews1) { //execute the viewsA + 1 }

Categories