Query returning additional empty variable - php

I'm running into some weird behaviour when calling values with SQL.
$result = mysqli_query($conn,"SELECT DISTINCT value FROM table ORDER BY value ASC");
while($row[] = mysqli_fetch_array($result));
$maxcat = count($row);
There are 8 unique values in my table, yet $maxcat returns "9". Am I missing something? I'm using the information to populate a list of categories. I knew I'd have to subtract one from maxcat to allow for $row[0], but I'm having to subtract two to make up for this empty value that won't get lost.
for ($i=0; $i<=($maxcat-2); $i++)
Cheers!
Thanks #scrowler & #faintsignal! Using mysqli_num_row() rather than count() is exactly what I needed. Functioning code below.
$result = mysqli_query($conn,"SELECT DISTINCT value FROM table ORDER BY value ASC");
$maxcat = mysqli_num_rows($result);
while($row[] = mysqli_fetch_array($result));

The while condition gets evaluated once for every row in your query result, plus one additional time to detect that there are no more rows left. So if you have 8 rows in your result, the while condition is evaluated 8 + 1 = 9 times. Hence you add 9 entries to your array $row, the final entry having the value NULL.
Note, if your while loop had a body, that body would only be iterated 8 times because the 9th time the condition would evaluate to false.
As #scrowler pointed out, if you just want to count the number of rows in the result, you can simply use mysqli_num_rows.

Related

Getting just the number of rows using Mysqli and PHP

I want to get how many (possibly 0) times a particular number occurs in a particular column. I set the number in $contact_client_ID then do the SELECT query below.
$sql = "SELECT * FROM t_contacts WHERE contact_client_ID ='$contact_client_ID'";
$result=(mysqli_query($link, $sql));
$count_result= mysqli_num_rows($result);
echo "contact client ID $contact_client_ID xxxxx $count_result";
Instead of $count_result containing the number I want, it contains a result made up of the number I want and the contact_client_ID joined together and the result doesn't seem to be usable as a number in any following code.
So, if $contact_client_ID = 50 and there are 2 occurrences of it in the table, the output I get is:
contact client ID 50 xxxxx 250
I've looked at the manuals and examples all over the place (including here) and I can't see what I'm doing wrong.
There are multiple ways of doing this, more precisely you have the option, to either do the count in PHP, or make your SQL server do the counting and just return the number:
Do it in PHP:
What it requires is: - fetch all data; -make a counter variable; - loop trough the data, for each loop increase counter +1
For small tables you can use PHP, for bigger ones I advice doing it on the SQL, since for PHP to count it it must fetch all the data.
$counter=0;
$query = "SELECT * FROM t_contacts WHERE contact_client_ID ='$contact_client_ID";
$res = $con->query($query);
while ($row = $res->fetch_assoc()) {
$counter++;
}
Do it in SQL
Now the smarter way would be to do it on the SQL server ,as it would handle the load better;
I would say what /u/Adaleni wrote is pretty close to what I would use:
$sql = "SELECT count(contact_client_ID) as total FROM t_contacts WHERE contact_client_ID ='$contact_client_ID'";
$result=mysqli_query($link, $sql);
$count_result= mysqli_fetch_row(result);
echo "contact client ID $contact_client_ID xxxxx $count_result[0]['total']";
Lets just describe what he does:
we use COUNT() function in SQL, this makes the server count the number of occurances of contact_client_ID and then make (in the result) a new variable called "total"
we execute the query and get the result
We use mysqli_fetch_rowm this function gets the result row as an enumerated array
then we access that array (as we know its only 1 item, we accessed index 0) and we print the variable total which we made in step 1 - $count_result[0]['total']
Try this
/* Select queries return a resultset */
if ($result = $mysqli->query("SELECT * FROM t_contacts WHERE contact_client_ID ='$contact_client_ID")) {
printf("Select returned %d rows.\n", $result->num_rows);

PHP While: prevent looping rows where one field is identical to another

I'm using a while loop to get some data from my database, however the problem I have is that it's looping everything inside it (as expected from the start) but now I wonder if it's possible for it to search for duplicated, and skip those? Depending on if a field is identical.
Let's say 3 rows are being looped, everyone have the field "number" but only the first 2 rows has the same value in the field "number". I want it to only loop the first one, and then skip the 2nd one as it already has the same value in the "number" field as the previous one. Is it possible?
$q = $database->query("SELECT * FROM table1 ORDER BY id DESC LIMIT 7");
while($f = $q->fetch_array()) {
echo $f["number"] . "<br />";
}
you can avoid duplicated elements on mysql by adding the DISTINCT keyword after select
SELECT DISTINCT id,nom,prenom FROM matable

PDO : how do I get the result of SELECT FOUND_ROWS()?

I am new to PDO, sorry that this is so simplistic.
Basically, I want to SELECT and both get the returned rows and the number of those rows, cheking for zero rows before processing further.
$rows = $conn->query('SELECT ...) allows me to foreach($rows as $row) but, as I said, I want to check for zero.
count($rows) always returns 1, even if there are no results(!).
I thought of using SELECT SQL_CALC_FOUND_ROWS followed by
$foundRows = $connection->exec('SELECT FOUND_ROWS() AS numRows'); but I am so dumb that I can't figure out how to get the number of rows from that.
Basically, I want to SELECT and both get the returned rows and the number of those rows,
you are selecting rows wrong way
$rows = $conn->query('SELECT ...')->fetchAll();
will actually give you $rows array which can be counted. However,
cheking for zero rows before processing further.
You don't need to count $rows for this. Just use $rows array itself:
id (!$rows) ... // no rows returned
As of the case where you INDEED need SELECT FOUND_ROWS() - then to get a result from the query, you should fetch it:
$foundRows = $connection->query('SELECT FOUND_ROWS()')->fetchColumn();
And remember that you should never use exec with PDO.

MySQL COUNT query results in 1 always

I'm wondering why my MySQL COUNT(*) query always results in ->num_rows to be equal 1.
$result = $db->query("SELECT COUNT( * ) FROM u11_users");
print $result->num_rows; // prints 1
Whereas fetching "real data" from the database works fine.
$result = $db->query("SELECT * FROM u11_users");
print $result->num_rows; // prints the correct number of elements in the table
What could be the reason for this?
Because Count(*) returns just one line with the number of rows.
Example:
Using Count(*) the result's something like the following.
array('COUNT(*)' => 20);
echo $result['COUNT(*)']; // 20
Reference
It should return one row*. To get the count you need to:
$result = $db->query("SELECT COUNT(*) AS C FROM u11_users");
$row = $result->fetch_assoc();
print $row["C"];
* since you are using an aggregate function and not using GROUP BY
that's why COUNT exists, it always returns one row with number of selected rows
http://dev.mysql.com/doc/refman/5.1/en/counting-rows.html
Count() is an aggregate function which means it returns just one row that contains the actual answer. You'd see the same type of thing if you used a function like max(id); if the maximum value in a column was 142, then you wouldn't expect to see 142 records but rather a single record with the value 142. Likewise, if the number of rows is 400 and you ask for the count(*), you will not get 400 rows but rather a single row with the answer: 400.
So, to get the count, you'd run your first query, and just access the value in the first (and only) row.
By the way, you should go with this count(*) approach rather than querying for all the data and taking $result->num_rows; because querying for all rows will take far longer since you're pulling back a bunch of data you do not need.

Checking if a value is in the db many times

I have a table A, with just two columns: 'id' and 'probably'. I need to go over a long list of ids, and determine for each one whether he is in A and has probability of '1'. What is the best way to do it?
I figured that it would be best to have 1 big query from A in the beginning of the script, and after that when I loop each id, I check the first query. but than i realized I don't know how to do that (efficiently). I mean, is there anyway to load all results from the first query to one array and than do in_array() check? I should mention that the first query should had few results, under 10 (while table A can be very large).
The other solution is doing a separate query in A for each id while I loop them. But this seems not very efficient...
Any ideas?
If you have the initial list of ids in array, you can use the php implode function like this:
$query = "select id
from A
where id in (".implode (',', $listOfIds).")
and probability = 1";
Now you pass the string as first parameter of mysql_query and receive the list of ids with probability = 1 that are within your initial list.
// $skip the amount of results you wish to skip over
// $limit the max amount of results you wish to return
function returnLimitedResultsFromTable($skip=0, $limit=10) {
// build the query
$query = "SELECT `id` FROM `A` WHERE `probability`=1 LIMIT $skip, $limit";
// store the result of the query
$result = mysql_query($query);
// if the query returned rows
if (mysql_num_rows($result) > 0) {
// while there are rows in $result
while ($row = mysql_fetch_assoc($result)) {
// populate results array with each row as an associative array
$results[] = $row;
}
return $results;
} else {
return false;
}
}
for each time you call this function you would need to increment skip by ten in order to retrieve the next ten results.
Then to use the values in the $results array (for example to print them):
foreach ($results as $key => $value) {
print "$key => $value <br/>";
}
Build a comma separated list with your ids and run a query like
SELECT id
FROM A
WHERE id IN (id1, id2, id3, ... idn)
AND probability = 1;
Your first solution proposal states that:
You will query the table A, probabyly using limit clause since A is a table with large data.
You will place the retrieved data in an array.
You will iterate through the array to look for the id's with probability of '1'.
You will repeat the first three steps several times until table A is iterated fully.
That is very inefficient!
Algorithm described above would require lots of database access and unneccessary memory (for the temporary array). Instead, just use a select statement with 'WHERE' clause and process with the data you want.
You need a query like the following I suppose:
SELECT id, probably FROM A WHERE A.probably = 1
If i understood you correctly, you should filter in the SQL query
SELECT * FROM A WHERE A.probably = 1

Categories