issue with SELECT COUNT(id) - php

I've been using this command to retrieve the number of the fields which have same email address:
$query = $db->query("SELECT COUNT(`user_id`) FROM `users` WHERE `email`='$email'") or die($db-error);
There are 3 records in users table with the same email address. The problem is when I put * instead of COUNT(user_id) it returns correctly: $query->num_rows gives 3 but when I use COUNT(user_id) then $query->num_rows returns 1 all the time. how can I correct this or where is my problem?

When you use $query->num_rows with that query it will return 1 row only, because there is only one count to return.
The actual number of rows will be contained in that query. If you want the result as an object, or associative array give the count a name:
$query = $db->query("SELECT COUNT(`user_id`) AS total FROM `users` WHERE `email`='$email'") or die($db-error);
And in the returned query total should be 3, while $query->num_rows will still be 1. If you just want the value a quick way would be using $total = $query->fetchColumn();.
As others have said though, be careful with NULL user ids, because COUNT() will ignore them.

Emails have to be uinque in users table. Thus, you need no count at all.
You ought to use prepared statements.
You shouldn't post a code that will never run.
Here goes the only correct way to run such a query:
$sql = "SELECT * FROM `users` WHERE `email`=?";
$stm = $db->prepare($sql);
$stm->execute([$email]);
$user = $stm-fetch();
(the code was written due to erroneous tagging. For mysqli you will need another code, but guidelines remains the same.)
Something like this
$sql = "SELECT * FROM `users` WHERE `email`=?";
$stm = $db->prepare($sql);
$stm->bind_param('s',$email);
$stm->execute();
$res = $stm->get_result()
$user = $res->fetch_assoc();
in $user variable you will have either userdata you will need in the following code or false which means no user found. Thus $user can be used in if() statement all right without the need of any counts.
In case when you really need to count the rows, then you use this count() approach you tried. You can use a function from this answer for this:
$count = getVar("SELECT COUNT(1) FROM users WHERE salary > ?", $salary);

That's the correct behaviour: If you use the COUNT function, the result of your select query will be just one row with one column containing the number of data sets.
So, you can retrieve the number of users with the given E-mail address like this:
$query = $db->query("SELECT COUNT(`user_id`) FROM `users` WHERE `email`='$email'") or die($db-error);
$row = $query->fetch_row();
$count = $row[0];
Note that this is faster than querying all data using SELECT * and checking $query->num_rows because it does not need to actually fetch the data.

Related

How to store a PHP variable from a SQL table INT camp

This is my table:
All I want to do is to obtain the '75' int value from the 'expquim' column to later addition that number into another (75+25) and do an UPDATE to that camp (now it is 100).
Foremost, there are dozens of ways to accomplish what you want to do. If you're querying the table, iterating over results and doing some conditional checks, the following will work for you. This is pseudo code... Check out the function names and what parameters they require. $db is your mysqli connection string. Obviously replace tablename with the name of your table. The query is designed to only select values that are equal to 75. Modify the query to obtain whatever results you want to update.
This should get you close to where you want to be.
$query = "SELECT * FROM tablename WHERE idus='1'";
$result = mysqli_query($db, $query);
while($row = mysqli_fetch_assoc($result)) {
if($row['expquim'] == 75){
$query2 = "UPDATE tablename SET expquim='".$row['expquim']+25."' WHERE idus='".$row['idus']."' LIMIT 1 ";
$result2 = mysqli_query($db,$query2);
}
}

How do I count unique rows in php pdo?

Here's my usual way of counting rows...
$query = "SELECT * FROM users";
$stmt = $db->prepare($query);
$stmt->execute();
$count = $stmt->rowCount();
This will count all rows, even if I use a WHERE clause, it'll still count every row that meets that condition. However, let's say I have a table, we'll call it tokensEarned (that's my actual table name). I have the following data...
user_id = 1,2,4,5,8,8,2,4,3,7,6,2 (those are actual rows in my table - clearly, user 1 has 1 entry, 2 has three entries, etc.) In all, I have 12 entries. But I don't want my query to count 12. I want my query to count each user_id one time. In this example, my count should display 8.
Any help on this? I can further explain if you have any specific questions or clarification you need. I would appreciate it. Thank You.
The following query will yield the distinct user count:
$query = "SELECT COUNT(DISTINCT user_id) AS cnt FROM users";
$stmt = $db->prepare($query);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
echo "distinct user count: " . $row['cnt'];
It isn't possible to get all records and the distinct count in a single query.
Whether you use the query above or you return all the actual distinct rows really depends on whether you need the full records. If all you need are the counts, then it is wasteful to return the data in the records, and what I gave above is probably the best option. If you do need the data, then selecting all distinct rows might make more sense.
You can use distinct in mysql to select only unique fields in your table.
$query = "SELECT distinct user_id FROM users";
$stmt = $db->prepare($query);
$stmt->execute();
$count = $stmt->rowCount();
Change your query to the following, this way you only shows the unique user_id:
$query = "SELECT DISTINCT user_id FROM users";

Check if PDO prepare(), execute() returns at least one row

Before moving to PDO, I used
$result = mysqli_query ($conn, 'SELECT * FROM mytable WHERE id = 54');
if (mysqli_num_rows($result) >= 1) { ... }
to check if the query returns at least one result.
Now with PDO, I've seen in many SO questions (like get number of rows with pdo) that there is no direct function in PDO to check the number of rows of a query (there are warnings about the use of$result->rowCount();), but rather solutions like doing an extra query:
SELECT count(*) FROM mytable WHERE id = 54
But this is maybe too much for what I want : in fact, I don't need the exact number of rows, but just if there is at least one.
How to check if a prepared statement query returns at least one row ?
$stmt = $db->prepare('SELECT * FROM mytable WHERE id = 54');
$stmt.execute();
... // HOW TO CHECK HERE?
$stmt = $db->prepare('SELECT * FROM mytable WHERE id = 54');
$stmt.execute();
... // HOW TO CHECK HERE?
It's so simple, you're almost there already.
$stmt = $db->prepare('SELECT * FROM mytable WHERE id = 54');
$stmt.execute();
$result = $stmt->fetchAll(); // Even fetch() will do
if(count($result)>0)
{
// at least 1 row
}
And if you just want Yes/No answer then you should also add a LIMIT 1 to your query so mysql doesn't waste trying to look for more rows.

sqlite3 - efficient way to count rows returned from SELECT statement in PHP without using COUNT()

I'm an SQL noob and learning how to use PDO. I'm doing a course which introduces basic user login functions. In an example of a login page, they check the username/password against a MySQL database. I edited their code slightly to be able to simultaneously check whether the user/pass combo exists and also grab the user's first name:
$sql = sprintf("SELECT firstname FROM users WHERE username='%s' AND password='%s'",
mysql_real_escape_string($_POST["username"]),
mysql_real_escape_string($_POST["password"]));
// execute query
$result = mysql_query($sql);
if (mysql_num_rows($result) == 1) {
$_SESSION["authenticated"] = true;
// get contents of "firstname" field from row 0 (our only row)
$firstname = mysql_result($result,0,"firstname");
if ($firstname != '')
$_SESSION["user"] = $firstname;
}
What I want to do is use SQLite instead and do the same thing. Searching around has only resulted in people saying you should use a SELECT COUNT(*) statement, but I don't want to have to use an extra query if it's possible. Since I'm SELECTing the firstname field, I should only get 1 row returned if the user exists and 0 if they don't. I want to be able to use that number to check if the login is correct.
So far I've got this:
$dsn = 'sqlite:../database/cs75.db';
$dbh = new PDO($dsn);
$sql = sprintf("SELECT firstname FROM users WHERE username='%s' AND password='%s'",
$_POST["username"],
$_POST["password"]);
// query the database and save the result in $result
$result = $dbh->query($sql);
// count number of rows
$rows = sqlite_num_rows($result);
if ($rows == 1) { ...
But this is returning Warning: sqlite_num_rows() expects parameter 1 to be resource, object given.
Is there a way I can do this efficiently like in MySQL, or do I have to use a second query?
EDIT:
I found this, not sure if it's the best way but it seems to work: How to get the number of rows grouped by column?
This code let me do it without the second query:
// query the database and save the result in $result
$result = $dbh->query($sql);
// count number of rows
$rows = $result->fetch(PDO::FETCH_NUM);
echo 'Found: ' . $rows[0];
$rows is an array so I can just count that to check if it's > 0.
Thanks to everyone who commented. I didn't know until now that there were 2 different approaches (procedural & object oriented) so that helped a lot.
Normally, you can use PDOStatement::rowCount(), however, SQLite v3 does not appear to provide rowcounts for queries.
You would need to seperately query the count(*), or create your own counting-query-function.
The documentation comments have an example of this
A bit late, but i tried this with SQLite3 successful:
$result = $db->query('SELECT * FROM table_xy');
$rows = $result->fetchAll();
echo count($rows);

MYSQL>PHP - Trouble with a query relating to function that checks if a table contains a row of user details

I am having trouble with a function that checks if a set of user entered info (username and password) exists within either of the two possible tables where this information is stored.
The first table is the users table. It contains the first set of specific user information.
The last table is the listings table. It contains the second set of specific user information.
I have basically modified my original code to include the new listings table, and hence the trouble coming from within that task. The old code basically counted the number of results in the users table, if the result was greater than 0, then the function returned true, else false.
Now I have been stuck on the best way to go about adding another table to the query, and function. So I have been playing around with a union.
This was the original query:
SELECT COUNT(*) FROM users
WHERE id='$accNum' AND password='$password'
This returned a count of either 0 or 1 based on the info stored in the users table.
This is how I have reworked the query to include a count of the additional listings table:
SELECT count . *
FROM (
SELECT COUNT( * )
FROM users
WHERE id = '$accNum'
AND PASSWORD = '$password'
UNION (
SELECT COUNT( * )
FROM listings
WHERE id = '$accNum'
AND PASSWORD = '$password'
)
)count
This returned a result set of two rows, the first relating to the users table, and the second relating to the listings table. Then a column called COUNT (*) that contained the result count. This is the result set that I see within php myadmin.
Now this is the function:
function databaseContainsUser($accNum, $password)
{
include $_SERVER['DOCUMENT_ROOT'] . '/../../includes/db.inc.php';
$accNum = mysqli_real_escape_string($link, $accNum);
$password = mysqli_real_escape_string($link, $password);
$sql = "SELECT count . *
FROM (
SELECT COUNT( * )
FROM users
WHERE id = '$accNum'
AND PASSWORD = '$password'
UNION (
SELECT COUNT( * )
FROM listings
WHERE id = '$accNum'
AND PASSWORD = '$password'
)
)count
";
$result = mysqli_query($link, $sql);
if (!$result)
{
$error = 'Error searching for user.';
include 'error.html.php';
exit();
}
$row = mysqli_fetch_array($result);
if ($row[0] > 0)
{
return TRUE;
}
else
{
return FALSE;
}
}
The problem that I have, is trying to work out how exactly to check the results to ascertain if the given log in credentials are valid.
I tried this: if (($row[0] > 0) || ($row[0] > 0)) But a var dump on $row showed that only the first row (count of users table) was being added to the array.
So I decided that this was complicated, and a long way to the final result.
So I tried selecting only the id column of the result as in:
...
`COUNT( * )` to `id`
...
$data = mysql_query($sql);
$num_sql = mysql_num_rows($data);
if ($num_sql > 0)
...
But this did not work out for me either.
But in either instance, my hours of trial and error have provided me with no success... So I've decided to seek help from the knowledgeable members of Stack Overflow!
So my question is this, what would be a logical way of going about this task? I am looking for any suggestions, or positive input what so ever here.
As I am fairly new to dabbling with PHP and mysql, if you would like to provide some code to explain your suggestions or input on the matter, it would more than likely help me to better understand the answer.
If you are checking existence only try doing this that way:
select case when
exists (SELECT 1 FROM users WHERE id = '$accNum' AND PASSWORD = '$password') or
exists (SELECT 1 FROM listings WHERE id = '$accNum' AND PASSWORD = '$password')
then 1 else 0
end as itDoesExist
It returns always one row with one column with 1 when record exists in at last one table (else 0).
Do not use count to check whether some specific record/-s exist/-s in table, it's usually slower than simple exists.
Looks like you're going to get two rows in the result no matter what. Try this:
$sql = "SELECT id,password
FROM users
WHERE id = '$accNum' AND password = '$password'
UNION
SELECT id,password
FROM listings
WHERE id = '$accNum' AND password = '$password'
";
Now you can just check mysql_num_rows() to see if there's a match in either of the tables.
There are a couple of ways to go about this; if we are to stick with the approach you started with; you can simplify the query to:
$sql = "SELECT COUNT(1) FROM users
WHERE id = '$accNum'
AND PASSWORD = '$password'
UNION (SELECT COUNT(1) FROM listings
WHERE id = '$accNum'
AND PASSWORD = '$password')";
The reason you are only seeing one result, is because thats the way mysql_fetch_array() works, try doing this to get all results:
while ($row = mysql_fetch_array($result)) {
$data[] = $row;
}
var_dump($data);
Now you should have both values in there to validate with your conditional statements.

Categories