Using PHP mysql_num_rows() returns "1" when running the query below on the table below when there are no matching rows present.
Upon testing I found out that the problem happens when I use the SUM() function in the query. If I take SUM() out of the query mysql_num_rows() returns "0" like it should.
Is there something else I should use instead of mysql_num_rows() to find out if there is a matching row in the table?
Table:
name | students_money | grade
George | 5 | A
Bill | 10 | A
Dan | 7 | A
Code:
$sql = "SELECT SUM(students_money) AS sum_money FROM students_table WHERE name = 'Tom' AND name = 'Jack'";
$result = #mysql_query($sql, $con) or die(mysql_error());
$num_rows = mysql_num_rows($result);
if ($num_rows < 1) {
echo "not everyone has paid";
exit;
}
while($row = mysql_fetch_array($result)) {
$sum_money = $row[sum_money];
$total = $total + $sum_money;
}
SUM() is an aggregate function. It takes all the rows that are returned for a group and adds them up.
Since you do not have a GROUP BY clause, it is adding up the values of all rows, even if there are none. It is then returning the total as a single row, so there should only be 1 row.
If you clarify what you want returned, I can try to help you write a statement to return it.
mysql_num_rows() tells you the number of rows returned by the database query. There is always a one row return in your case because there is always one a sum. The sum may be 0 of course.
It may be a good idea to test your query in the mysql query browser. Perhaps you are looking for something like this?
SELECT name, SUM(students_money) AS sum_money
FROM students_table
GROUP BY name;
This will group the sums on a per name basis. To skip 0 sums you can add this:
HAVING sum_money > 0;
Related
So I have this query like this
$sql2 = "SELECT count(*) FROM comments WHERE YourUsername = '$MyUsername' AND PostId = '$PostId'";
if ($result2=mysqli_query($conn,$sql2))
{
// Return the number of rows in result set
$rowcount=mysqli_num_rows($result2);
echo $rowcount;
}
and I have 2 rows in my database which meet the clause requirements but for some reason it keeps outputting 1 as the result. How do I make it display the actual count and not just 1 when in reality the count is 2 and so on for future rows.
You're SELECTing the count of the rows in your first line, so when the query is run, it's returning the row count into $result2. You don't need to use mysqli_num_rows.
Foul
I have a function for getting path in a tree structure data.
According to my table in DB, root should get no result when I query sub_id='root_id'
When I just pass the root the rowCount return correct result which is 0. However when I pass a node from lower rank(3rd), in the end of the recursive which is root, rowCount return 1?
PS
I use Mysql as DB
This is my table
main_id | sub_id
----------------
1 | 2
1 | 3
2 | 4
3 | 5
The code:
$stmt = $conn->prepare("Select * from table where sub_id= ? ");
function get_path($stmt,$node,&$map){
$res=$stmt->execute(array($node));
if(!$res){ throw new Exception( implode(' ',$stmt->errorInfo()),1); }
echo $node.' found '.$stmt->rowCount().'<br>';
if($stmt->rowCount()==0){ //root
$map[]=$node;
}else{
foreach($stmt->fetchAll(PDO::FETCH_ASSOC) AS $row){
$map[]=$node;
$upper_node=$row['main_id'];
get_path($stmt,$upper_node,$map);
}
}
}
If I just pass get_path($stmt,1,$map); (the root)
the output:
1 found 0
but when I for example pass 4 into it
the output become:
4 found 1
2 found 1
1 found 1 <= it should found 0
Why?
You shouldn't rely on PDOStatement::rowCount() to get the number of rows affected by a SELECT statement, see PHP manual, PDOStatement::rowCount:
DOStatement::rowCount() returns the number of rows affected by the
last DELETE, INSERT, or UPDATE statement executed by the corresponding
PDOStatement object.
If the last SQL statement executed by the associated PDOStatement was
a SELECT statement, some databases may return the number of rows
returned by that statement. However, this behaviour is not guaranteed
for all databases and should not be relied on for portable
applications.
[...]
Example #2 Counting rows returned by a SELECT statement
For most databases, PDOStatement::rowCount() does not return the
number of rows affected by a SELECT statement. Instead, use
PDO::query() to issue a SELECT COUNT(*) statement with the same
predicates as your intended SELECT statement, then use
PDOStatement::fetchColumn() to retrieve the number of rows that will
be returned. Your application can then perform the correct action.
It is probably something to do with this from PDO rowCount Docs:
"If the last SQL statement executed by the associated PDOStatement was a SELECT statement, some databases may return the number of rows returned by that statement. However, this behaviour is not guaranteed for all databases and should not be relied on for portable applications."
In other words rowCount only really works with DML, and I believe this is the case in MySQL.
You have to count the fetched results to get the guaranteed row count.
Eg of #VMai 's Correct Answer:
$query = $db->prepare("
SELECT COUNT(*) FROM table
WHERE
whatever
");
$query->execute();
$result = $query->fetchColumn();
if ($result > 5)
{
echo "Result is greater than 5";
}
else
{
echo "Result is less than 5";
}
?>
Note: You will need to run the "real" SQL Query again, except without COUNT(*).
if($sql = $db->query("Count (*) FROM post_items")){
echo mysqli_num_rows($sql);
}
what's wrong with my code? is this the correct way to echo the total of row in a table?
Your query should be
select count(*) FROM post_items
but echoing
mysqli_num_rows($sql);
will always give 1 as the ans, because count function returns only one row.
Rather fetch the details and show the count
$row = $sql->fetch_row();
echo $row[0];
No it is not; you will always get a return value of 1.
Why? Because you are in essence double-counting. The query executes a COUNT aggregate on the table returning a single row with the counted number. mysqli_num_rows is then counting the number of rows in this result set - the single row - and returns 1.
Try, the following line instead, which should fetch the first (only) column returned of the first (only) row in the result set.
echo $sql->fetch_row()[0]
Note you're also missing a SELECT keyword in your SQL statement.
It should be
if($sql = $db->query("select count(*) FROM post_items")){
echo mysqli_num_rows($sql);
}
I have two different functions:
function user_count(){
global $db;
$query = mysqli_query($db,"SELECT COUNT(user_id) FROM users");
if($result = $query){
$user_count = mysqli_num_rows($result);
mysqli_free_result($result);
return $user_count;
}
}
In this function, I query the database to tell me how many users there are, and in PHP I use user_count(). The result of this function is 1. Which is correct, because I only have only 1 users in the database at the moment.
However when I use the same code for a different function such as:
function user_exists($username){
global $db;
sanitize($username);
$query = mysqli_query($db,"SELECT COUNT(user_id) FROM users WHERE username=".$username) or die ("Doesn't work");
if($result = $query){
$user_exists = mysqli_num_rows($result);
mysqli_free_result($result);
return $user_exists;
}
}
Not to mention I have also tried to comment out the sanitize($username). But even with it commented out I still am getting an error.
And I use the function user_exists("superadmin"), I get the error "Doesn't work". I am wondering what am I doing wrong in the second function where the first function would return the number of rows, where as second function would return an error.
I know for certain that:
Database is connecting
String sanitization is working
User does exists on the database
If would much appreciated if you reply using the procedural style.
To paraphrase a wise man, "This is not the count you are looking for"
mysqli_num_rows will return the number of rows in the result set which, in this case, will always be 1.
To get the actual count, you will have to use $row=mysqli_fetch_row($result) and then the count you want is in $row[0];
Also, you're not creating your query properly - the query should have single quote marks around the variable. Even better, look at using prepared statements as they will take care of all the escaping and quoting for you
You're asking for the number of user_ids in the table users, so the MySQL server will return something like this:
mysql> SELECT COUNT(user_id) FROM users;
+----------+
| count(*) |
+----------+
| 36 |
+----------+
1 row in set (0.00 sec)
Then, you're using mysqli_num_rows which checks the result of the query to see how many rows were returned. But, as you can see, there's "1 row in set" - so you're getting back the number of rows in the result of the query, not the number of user_ids.
What you want to do is something like this:
$row = mysqli_fetch_row($result);
$num_user_ids = $row[0];
Because $row[0] contains the first field in the row, which is 36 in my example.
As for the second part, you'll want to bind parameters, like this:
$stmt = $mysqli->prepare("SELECT COUNT(user_id) FROM users WHERE username = ?");
$stmt->bind_param('s', $username);
The s means that you're replacing the ? in the first row above with a string, which is given in the second argument.
You could also do what you do, but you'll have to surround $username with single quotes, because the query won't do it for you.
You are only getting one row from mysqli_num_rows in the first function because there is only one row in the result set (the row with the COUNT value in it). If you want to get the value you need to actually read the result set. Alternatively you could not use the COUNT function in the first case and then use mysqli_num_rows.
In the second function, my guess is that you need to add single quotes around the username value you are searching for. You should look at your actual errors returned from the query though and work from that.
Take this table:
id | field1 | foreign
1 abc 12
2 def 12
3 abc 13
4 def 13
I select this record like this:
"SELECT field1 FROM table WHERE foreign = 12"
AND
"SELECT field1 FROM table WHERE foreign = 13"
Now considering my table this select returns exactly the same records value.
How can I tell that given 2 arbitrary SELECT they retunrs the same value in SQL?
PS. Considering you were voting to close this question I have reformulated it. thanks
PS2. I have other field other than field1
PS3. I know I can do it via PHP, but is there a way pure-SQL?
You can use md5sum to confirm whether 2 result sets are equal or not, this is very useful when comparing two large result sets. Just use the following command within mysql console:
pager md5sum -
This will set the MySQL pager to display the MD5Sum after every query that is run.
If you are using PHP to run each query then you could create the same effect using this method:
// This method will return MD5 of a result set. Compared results will return the same MD5Sum if they have the same results, and are ordered in the same way.
function query_md5($sql) {
$rs = mysql_query($sql);
$num = mysql_num_fields($rs);
$str = "";
while ($obj = mysql_fetch_array($rs)) {
$i = 0;
while ($i < $num) {
// no need for spaces or formatting
$str .= $obj[$i++];
}
}
return md5($str);
}
Hope this helps!