MySQL error: 'invalid use of a group function' [duplicate] - php

This question already has answers here:
Call to a member function bind_param() on a non-object [duplicate]
(6 answers)
Closed 7 years ago.
I have a referral application where an ID can only have 2 direct referrals. I am trying to find IDs which appear less than 2 times in the ID_REF field with the code below.
$stmt = $conex->prepare("SELECT id FROM tb_modules WHERE count(id_ref) < ? ORDER BY id DESC LIMIT 1");
$stmt->bind_param("s", $n);
$n = 2;
$stmt->execute();
$stmt->store_result();
$numrows = $stmt->num_rows;
$stmt->bind_result($id);
//$stmt->fetch();
$stmt->close();
//echo $id.' '.'oi';
while ($stmt->fetch()) {
echo $id;
}

You aren't checking for any errors, that is completely bad development. You should start by ensuring that your prepare() is actually preparing the query correctly and not failing...
$stmt = $conex->prepare("SELECT id FROM tb_modules WHERE count(id_ref) < ? ORDER BY id DESC LIMIT 1");
// now check
if(!$stmt) {
die($conex->error); // or mysqli_error($conex);
} else {
$stmt->bind_param('s', $n);
}
Back to other matters. You seem to be trying to compare count(id_ref) which would be a number (int) against $n (which is an int too) but you're trying to pass it as a string.....?
You'll need to change that bind of yours to something like:
$stmt->bind_param('i', $n);
Also note, you can't set the $n variable after you call it.... that's going to throw an error.

Do the following:
var_dump($conex);
$stmt = $conex->prepare("SELECT id FROM tb_modules WHERE count(id_ref) < ? ORDER BY id DESC LIMIT 1");
var_dump($stmt)
This should shed some light on the matter.
I'm betting the $stmt variable is bool or null.

Your code isn't checking whether prepare returned successfully.
If the prepare encounters an error, it returns FALSE. instead of a statement object.
And a boolean FALSE value (the return from prepare) does not have a method/function bind_param.
$stmt = $conex->prepare("...");
if(!$stmt) {
echo "error in prepare ". mysqli_error($conex) ;
} else {
// prepare returned a statement object so we can do a bind_param
$stmt->bind_param(...);
To fix a syntax issue in the SQL statement that's causing an error in prepare, replace they keyword WHERE with keyword HAVING.
The predicates (conditions) in the WHERE clause are evaluated when rows are accessed. So the result of an aggregate function (e.g. COUNT() is not going to be available at the time those conditions in the WHERE are check. There's no way for that condition to be evaluated until after the rows are accessed, and the aggregate functions are evaluated. Predicates (conditions) in the HAVING clause get evaluated later, so it's valid to reference aggregates in a HAVING clause.
Just making that change to the SQL statement isn't likely going to get you the result you are looking for. Without a specification, we're just guessing what you are trying to return.

Related

Same query but different results in phpMyAdmin and PHP [duplicate]

This question already has an answer here:
PDO, MySQL SELECT statement returning boolean true?
(1 answer)
Closed 11 months ago.
I have seen similar posts to this one already existing but none of them have helped.
When I run this PHP code with $retrievestat = 1, I get a value of 1 return by the search query in php:
$retrievestat = $_POST["statIdentifier"];
echo $retrievestat;
// Retrieve The Player With The Most Rounds Won With Their Rounds
if ($retrievestat == 1)
{
$checkuniquequery = "SELECT COUNT(*) FROM playerstats WHERE roundswon = (SELECT MAX(roundswon) FROM playerstats);"; // Get number of rows that have a roundswon value equal to the max in the table
$stmt = $conn->prepare($checkuniquequery);
echo ($stmt->execute());
if ($stmt->execute() == 1) // If only one row has the max roundswon then get the username + roundswon
{
$mostroundswonquery = "SELECT username, MAX(roundswon) FROM players, playerstats WHERE players.id = playerstats.id";
$stmt = $conn->prepare($mostroundswonquery);
//echo ($stmt->execute());
}
However, when I run this query in phpMyAdmin:
"SELECT COUNT(*) FROM playerstats WHERE roundswon = (SELECT MAX(roundswon) FROM playerstats);"
I get 2 returned as the output.
Any ideas why this is happening and how to fix it?
The execute method on PDO statement ($stmt->execute()) does return either true (if execution was successful) or false if not. It does not return the return value of the SQL statement. On a side node: $stmt->execute() == 1 does behave the same as $stmt->execute() == true !
To get the actual return value you need to fetch the result after execution.
E.g. you can use $stmt->fetch() to get actual result.
Have a look at the documentation to learn more: https://www.php.net/manual/en/class.pdostatement.php

MySQLi Prepared Statement not working in WHILE Loop

I'm working on a query inside a While loop. However, the Second run is not working. (The While is ended later, after some results get echoed). I've tried calling the second query $stma, however this resulted in the same error.
Error
Fatal error: Call to a member function bind_param() on a non-object in PATH on line 96
Code
// Prepare Query
$stmt = $db->prepare("SELECT id, fullname, shortname FROM languages WHERE (state = '0')");
$stmt->execute();
// Get result from query.
$stmt->bind_result($lang_id, $lang_name, $lang_short);
// While Loop
while($language = $stmt->fetch()){
// Get Language Texts
$stmt = $db->prepare("SELECT id, article_id, article_language, article_text, article_recuse, article_spec FROM article_content WHERE article_id = ? AND article_language = ?");
$stmt->bind_param("is", $artikel_nummer, $lang_short); // This is line 96.
$stmt->execute();
// Get result from query.
$stmt->bind_result($t_id, $t_articleid, $t_language, $t_text, $t_recuse, $t_spec);
$stmt->fetch();
I'm fairly new to prepared statements, so I'm not sure what exactly the problem is. I've ran a var_dump() on the query and it returned false, however, running the query elsewhere or outside the WHILE loop is working (When I Define the two variables by hand).
I've echoed $artikel_nummer and $lang_short, and it returns their values.
The question is the following: Why is the second query not running, and thus returning the error as stated above?
In your loop, you are overriding your $stm variable which holds a reference to your initial prepared statement (and indeed is the condition of your loop). For all queries happening inside loop, you must choose a different variable name:
while($language = $stmt->fetch()){
// Get Language Texts
$_stmt = $db->prepare("SELECT id, article_id, article_language, article_text, article_recuse, article_spec FROM article_content WHERE article_id = ? AND article_language = ?");
$_stmt->bind_param("is", $artikel_nummer, $lang_short); // This is line 96.
$_stmt->execute();
// Get result from query.
$_stmt->bind_result($t_id, $t_articleid, $t_language, $t_text, $t_recuse, $t_spec);
$_stmt->fetch();
}

SELECT ? FROM table WHERE id = ? not working correctly [duplicate]

This question already has answers here:
Can PHP PDO Statements accept the table or column name as parameter?
(8 answers)
Closed 6 years ago.
I've got a little question. I want to get specific information out of my database via mysqli query:
public function get_searchorder_single_information($soid, $information) {
global $mysqli;
$stmt = $mysqli->prepare("SELECT ? FROM pr_hr_searchorders WHERE id = ?");
$stmt->bind_param('si', $information, $soid);
$stmt->execute();
$stmt->bind_result($result);
$stmt->fetch();
echo $result;
$stmt->close();
}
In my example, $information is set 'job', but it can have other values, too (e.g. 'salary'). When I try to use my query with this variable, echo outputs just 'job' and not the value that is saved in my database. When I write 'job' instead of the '?', echo outputs the correct value.
So now I could make a function for each information I search, but this would end in spaghetti code. So I ask you if there is any possibility to use my search query like above with correct output. How would I do that?
Thanks in advance and sorry for my bad english writing.
Read documentation : http://php.net/manual/en/mysqli.prepare.php
The markers are legal only in certain places in SQL statements. For
example, they are allowed in the VALUES() list of an INSERT statement
(to specify column values for a row), or in a comparison with a column
in a WHERE clause to specify a comparison value. However, they are not
allowed for identifiers (such as table or column names), in the select
list that names the columns to be returned by a SELECT statement, or
to specify both operands of a binary operator such as the = equal
sign. The latter restriction is necessary because it would be
impossible to determine the parameter type. It's not allowed to
compare marker with NULL by ? IS NULL too. In general, parameters are
legal only in Data Manipulation Language (DML) statements, and not in
Data Definition Language (DDL) statements.
Modify your code :
$stmt= $mysqli->prepare("SELECT $information FROM pr_hr_searchorders WHERE id = ?");
$stmt->bind_param('i', $soid);
Change your code to
public function get_searchorder_single_information($soid, $information) {
global $mysqli;
$query = "SELECT".$information." FROM pr_hr_searchorders WHERE id = ?"
$stmt = $mysqli->prepare($query);
$stmt->bind_param('si', $soid);
$stmt->execute();
$stmt->bind_result($result);
$stmt->fetch();
echo $result;
$stmt->close();
}
Then you will get the desired result

Add up all rows where value is equal to ID

I've been looking up around for a couple tutorials of this and I've seemed out of luck. Basically, I have a database containing a winner's user ID (corresponding to the winners user ID) and a loser's ID. I am trying to create a members profile where it counts up all the rows the member has won. Here is what I have came up with:
$web = mysqli_query("select SUM(matches) WHERE WinnerUID='".$req_user_info['id']."'");
$web_sum=mysqli_fetch_assoc($web);
echo $web_sum;
Unfortunately, it doesn't display any number. Can anyone help?
I think you're looking for COUNT() not SUM(). And you didn't include a table name. Also remember that mysqli_fetch_assoc() returns the row as an array, it doesn't return the first column's value. Also, mysqli_query() requires the connection as the first argument.
$web = mysqli_query($conn, "select COUNT(*) as total FROM matches WHERE WinnerUID='".(int)$req_user_info['id']."'");
$row = mysqli_fetch_assoc($web);
echo $row['total'];
Don't concatenate variables into your SQL. Use a Prepared Statement with bound parameters. I have casted your ID as an (int) in the above code, which is a quick fix but you should switch to a Prepared Statement.
Prepared Statement example (object oriented interface instead of procedural):
if ($stmt = $conn->prepare("select COUNT(*) from matches WHERE WinnerUID = ?")) {
$stmt->bind_param("i", $req_user_info['id']);
$stmt->execute();
$stmt->bind_result($web_sum);
$stmt->fetch();
echo $web_sum;
$stmt->close();
}

What does this SQL statement do?

I am trying to understand this SQL statements :
$id = 5;
$stmt = $conn->prepare('SELECT * FROM myTable WHERE id = :id');
$stmt->execute(array('id' => $id));
while($row = $stmt->fetch()) {
print_r($row);
}
Can someone please explain me step by step what exactly is going on here?
From what i understand :
$stmt = $conn->prepare('SELECT * FROM myTable WHERE id = :id');
1) $stmt is about to take as iinput an SQL query. The SQL query is to select all the rows from a table that their id is equal to 5.
$stmt->execute(array('id' => $id));
2) We execute the statement. Now the $stmt has these rows?
$row = $stmt->fetch()
3) This is the most confusing line for me. What exactly happens here? Variable "row" takes one by one the rows that have id = 5 ? Is that what fetch() does ? And if yes , how exaxtly does it return the results? Its an array of all the correct answers? EG all the rows that have id = 5 ? I dont understand how exactly this while loop works here.The first time it runs "row" will have the first row ? The second time it runs , will have the second row that satisfies our creteria (id = 5) and so on? Is it like that every time i run fetch one result will be returned? And next time i run fetch , the next result , till there is no more result to satisfy the query?
I thing i am so close to get this one. Anything that could help me understand it completely would be highly appreciated !
I'll explain as comments:
$id = 5;
// Create a prepared statement - don't actually execute the statement yet.
// The :id value in the statement will be replaced by a parameter value (safely) when the
// statement is executed
$stmt = $conn->prepare('SELECT * FROM myTable WHERE id = :id');
// Execute the statement against the DB - the $stmt var now contains the result set for the
// executed statement. e.g. it contains *all* the results that the query fetched
$stmt->execute(array('id' => $id));
// Now we loop through the rows in the result set (they are all in memory at this point).
// "fetch" will start from row 1 and return the next result each time you call it again.
// when there are no more rows it returns FALSE and therefore breaks out of the while loop
while($row = $stmt->fetch()) {
print_r($row);
}
Just checking docs also and whilst this is how it was done previously (been years since I've touched PHP) it looks like stmt->fetch() actually places results into bound variables:
http://php.net/manual/en/mysqli-stmt.fetch.php
$row = array();
stmt_bind_assoc($stmt, $row);
// loop through all result rows
while ($stmt->fetch())
{
print_r($row);
}
Does the code you originally posted actually work? It doesn't appear you bind any variables and therefore since the $stmt-fetch() call returns bool TRUE/FALSE it would seem to be that $row would not get set to anything but TRUE/FALSE
here it uses PDO for execution,
Repeated SELECT using prepared statements through which you can call repeated query
$stmt = $conn->prepare('SELECT * FROM myTable WHERE id = :id');
it defines the prepared statement where :id is placeholder
$stmt->execute(array('id' => $id));
this places assigns the value to placeholder and execute the query
$row = $stmt->fetch()
it fetch the record from select
for more reference visit the link
http://www.php.net/manual/en/pdo.prepared-statements.php

Categories