Counting number of SELECTED rows in Oracle with PHP - php

I'm doing this project for university, which is basically a movie database and for a couple of queries I need to know how many rows were selected. For now, there's 2 situations where I need this:
Display a single movie information. I want the count of selected rows to know if the database contains the selected movie by the user. Or is there a better solution for this?
That selected movie has genres, I need to know how many so that I can construct a string with the genres separated by | without adding one to the end of the string.
With MySQL this is easy, I just query the database and use mysql_num_rows() but oci_num_rows() doesn't work quite the same for the SELECT statement.
The only solution I found with OCI/PHP is this:
if(is_numeric($mid) && $mid > 0) {
$stid = oci_parse($db,
'SELECT COUNT(*) AS NUM_ROWS
FROM movies
WHERE mid = '.$mid
);
oci_define_by_name($stid, 'NUM_ROWS', $num_rows);
oci_execute($stid);
oci_fetch($stid);
if($num_rows > 0) {
$stid = oci_parse($db,
'SELECT title, year, synopsis, poster_url
FROM movies
WHERE mid = '.$mid
);
oci_execute($stid);
$info = oci_fetch_assoc($stid);
$stid = oci_parse($db,
'SELECT COUNT(*) AS NUM_ROWS
FROM genres g, movies_genres mg
WHERE mg.mid = '.$mid.' AND g.gid = mg.gid'
);
oci_define_by_name($stid, 'NUM_ROWS', $num_rows);
oci_execute($stid);
oci_fetch($stid);
$stid = oci_parse($db,
'SELECT g.name AS genre
FROM genres g, movies_genres mg
WHERE mg.mid = '.$mid.' AND g.gid = mg.gid');
oci_execute($stid);
$genres_list = null;
while($row = oci_fetch_assoc($stid)) {
$genres_list .= $row['GENRE'];
if($num_rows > 1) {
$genres_list .= ' | ';
$num_rows--;
}
}
$Template->assignReferences(array(
'Index:LinkURI' => $link_uri,
'Movie:Title' => $info['TITLE'],
'Movie:Year' => $info['YEAR'],
'Movie:GenresList' => $genres_list,
'Movie:Synopsis' => $info['SYNOPSIS'],
'Movie:PosterURL' => $info['POSTER_URL'] // FIX: Handle empty poster link
));
$Template->renderTemplate('movieinfo');
} else {
// TODO: How to handle this error?
}
} else {
// TODO: How to handle this error?
}
But I don't like it. I always need to make 2 queries to count the rows and then select the actual data and there's too many lines of code just to count the rows.
This code doesn't show it (haven't done it yet cause I'm looking for a better solution) but I'll also need to do the same for the movie directors/writers.
Is there any better and simpler solution to accomplish this or this is the only way?
I could add separators in the fetch loop until it finishes and then use PHP functions to trim the last separator from the string, but for this project I'm forced to use SEQUENCES, VIEWS, FUNCTIONS, PROCEDURES and TRIGGERS. Do any of these help solving my problem?
I know what SEQUENCES are, I'm using them already but I don't see how can they help.
For VIEWS, they probably wouldn't simplify the code that much (it's basically a stored query right?). For FUNCTIONS, PROCEDURES and TRIGGERS, as far as I understand them, I can't see how can they be of any help either.
Solutions?

Why do the initial count at all? Just issue your select for the movie title. If it's not found, do your error processing. If it is, continue on! If you really need the count, use an analytic to add the count to your query:
'SELECT title, year, synopsis, poster_url
, COUNT(*) OVER (PARTITION BY mid) mcount
FROM movies
WHERE mid = '.$mid
The same goes for your genre selection.
EDIT:
Oracle documentation on Analytic Functions link. I found that analytics are a bit difficult to get from the Oracle docs. Analytic functions by Example by Shouvik Basu provides some simple guidance as to how to use them and helped me quite a bit.

You can try this
$conn = oci_pconnect('user', 'password', 'connectionstring');
$resource = oci_parse($conn, $sql);
oci_execute($resource, OCI_DEFAULT);
$results=array();
$numrows = oci_fetch_all($resource, $results, null, null, OCI_FETCHSTATEMENT_BY_ROW);
Cheers

you can use the ocirowcount it should behave just like mysql_num_rows when making a select

oci_num_rows() Will give you the total row count if executed AFTER oci_fetch_array()

Related

remove empty results with a 2nd query from array mysqli

I have 2 tables, 1 with companies(Costcenters) and one with clients (employees of those companies)
i need to make a form to edit or delete malformed ( like john smit and j. Smit) from those companies employees grouped by company (Costcenter), when i make a list with all those companies i get a lot of companies that has no clients. So I made a array of the companies (Costcenters) and check first if they have employees, this with the goal to remove the Costcenters without employees from the array ($bedrijven).
The form is no problem, but i cant find a way to get those companies removed from the bedrijven array.
require_once('conn.php');
$query = "SELECT bedrijfID, Houder, Costcenter, Actief FROM bedrijven
WHERE Actief = 'actief' ORDER BY Costcenter";
$results = mysqli_query($conn, $query);
if (!$results) printf("Query failed: %s\n", $conn->error);
$bedrijven = [];
while($row = mysqli_fetch_assoc($results)) {
$bedrijven[] = $row['Costcenter'];
}
foreach ($bedrijven as $key => $item) {
$query1 = "SELECT * from customer where Costcenter = '$item' ORDER by
Client";
$customerresult = mysqli_query($conn, $query1) or
die(mysqli_error($conn));
if (!$customerresult) printf("Query failed: %s\n", $conn->error);
if($customerresult->num_rows === 0) {
unset($bedrijven[$key]);
}
}
I am not familiar with PDO or funtions so tried it this way that does not work as i expected, the unset is not working.
the code is editted as it is working now, i hope it might help others as well. If any has a better solution please post.
If I understand what you are going for, this is better done as a single Query. A JOIN can be used first to bind your tables, and then additional WHERE operators can be used if needed to refine your search. I'm not 100% sure if I'm reading right that this is is exactly how you wanted to join the data, but if you play with different JOIN operators you'll get it.
$query = "SELECT Costcenter.bedrijfID, Costcenter.Houder, Costcenter.Costcenter, Costcenter.Actief, customer.* FROM Costcenter
LEFT JOIN customer ON customer.Costcenter = Costcenter.Costcenter
WHERE Actief = 'Costcenter.actief' AND Costcenter.Costcenter != "" ORDER BY Costcenter.Costcenter";
The biggest reason for doing it this way this that a single SQL call processes WAY faster than trying to parse your data from multiple calls in PHP.
thanks to the requestion of The fouth bird i discovered i have been wasting a lot of time on a simple solution. i should not have done :
unset($bedrijven['Costcenter']);
but
unset($bedrijven[$key]);
you must unset the key in the array not the value....

How to count the amount of same results in column?

I've developed a database, where i have three sets of columns:
- Username
- Feeling
- Remark
The entry's for feelings are all the same, because they're being selected from a dropdown menu. I'm looking for a way to count the amount of same results and then echo it on a site with PHP, but I can't get any further than this:
<?php
$con=mysqli_connect("localhost","username","password", "database");
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$query = "SELECT COUNT(*) FROM thefeels WHERE feeling = 'Happy'";
$result = mysqli_query($con, $query);
var_dump($result)
?>
In this code I want to count the amount of times happy occurs in a column, but even that is not working. How can I count the amount of times the same results is in a column?
So if Happy is there four times and Sad two times it should display:
Happy: 4
Sad: 2
This is a basic Counting Rows task. You will find some examples in the official documentation.
In your case it would be:
$query = "SELECT feeling, COUNT(*) as count FROM thefeels GROUP BY feeling";
$result = mysqli_query($con, $query);
Now you can use the "old school" way (which you will find in many totorials):
while ($row = mysqli_fetch_assoc($result)) {
echo "{$row['feeling']}: {$row['count']}<br>";
}
or move forward and separate data fetching from data processing and data output with:
$feelingCounts = $con->fetch_all(MYSQLI_ASSOC);
And do what ever you need with the fetched data. For example:
var_dump($feelingCounts);
Use conditional aggregation:
SELECT COUNT(CASE WHEN feeling = 'Happy' THEN 1 END) as Happy,
COUNT(CASE WHEN feeling = 'Sad' THEN 1 END) as Sad
FROM thefeels

Select from two tables with if condition and delete [duplicate]

There are many conflicting statements around. What is the best way to get the row count using PDO in PHP? Before using PDO, I just simply used mysql_num_rows.
fetchAll is something I won't want because I may sometimes be dealing with large datasets, so not good for my use.
Do you have any suggestions?
$sql = "SELECT count(*) FROM `table` WHERE foo = ?";
$result = $con->prepare($sql);
$result->execute([$bar]);
$number_of_rows = $result->fetchColumn();
Not the most elegant way to do it, plus it involves an extra query.
PDO has PDOStatement::rowCount(), which apparently does not work in MySql. What a pain.
From the PDO Doc:
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.
EDIT: The above code example uses a prepared statement, which is in many cases is probably unnecessary for the purpose of counting rows, so:
$nRows = $pdo->query('select count(*) from blah')->fetchColumn();
echo $nRows;
As I wrote previously in an answer to a similar question, the only reason mysql_num_rows() worked is because it was internally fetching all the rows to give you that information, even if it didn't seem like it to you.
So in PDO, your options are:
Use PDO's fetchAll() function to fetch all the rows into an array, then use count() on it.
Do an extra query to SELECT COUNT(*), as karim79 suggested.
Use MySQL's FOUND_ROWS() function UNLESS the query had SQL_CALC_FOUND_ROWS or a LIMIT clause (in which case the number of rows that were returned by the query and the number returned by FOUND_ROWS() may differ). However, this function is deprecated and will be removed in the future.
As it often happens, this question is confusing as hell. People are coming here having two different tasks in mind:
They need to know how many rows in the table
They need to know whether a query returned any rows
That's two absolutely different tasks that have nothing in common and cannot be solved by the same function. Ironically, for neither of them the actual PDOStatement::rowCount() function has to be used.
Let's see why
Counting rows in the table
Before using PDO I just simply used mysql_num_rows().
Means you already did it wrong. Using mysql_num_rows() or rowCount() to count the number of rows in the table is a real disaster in terms of consuming the server resources. A database has to read all the rows from the disk, consume the memory on the database server, then send all this heap of data to PHP, consuming PHP process' memory as well, burdening your server with absolute no reason.
Besides, selecting rows only to count them simply makes no sense. A count(*) query has to be run instead. The database will count the records out of the index, without reading the actual rows and then only one row returned.
For this purpose the code suggested in the accepted answer is fair, save for the fact it won't be an "extra" query but the only query to run.
Counting the number rows returned.
The second use case is not as disastrous as rather pointless: in case you need to know whether your query returned any data, you always have the data itself!
Say, if you are selecting only one row. All right, you can use the fetched row as a flag:
$stmt->execute();
$row = $stmt->fetch();
if (!$row) { // here! as simple as that
echo 'No data found';
}
In case you need to get many rows, then you can use fetchAll().
fetchAll() is something I won't want as I may sometimes be dealing with large datasets
Yes of course, for the first use case it would be twice as bad. But as we learned already, just don't select the rows only to count them, neither with rowCount() nor fetchAll().
But in case you are going to actually use the rows selected, there is nothing wrong in using fetchAll(). Remember that in a web application you should never select a huge amount of rows. Only rows that will be actually used on a web page should be selected, hence you've got to use LIMIT, WHERE or a similar clause in your SQL. And for such a moderate amount of data it's all right to use fetchAll(). And again, just use this function's result in the condition:
$stmt->execute();
$data = $stmt->fetchAll();
if (!$data) { // again, no rowCount() is needed!
echo 'No data found';
}
And of course it will be absolute madness to run an extra query only to tell whether your other query returned any rows, as it suggested in the two top answers.
Counting the number of rows in a large resultset
In such a rare case when you need to select a real huge amount of rows (in a console application for example), you have to use an unbuffered query, in order to reduce the amount of memory used. But this is the actual case when rowCount() won't be available, thus there is no use for this function as well.
Hence, that's the only use case when you may possibly need to run an extra query, in case you'd need to know a close estimate for the number of rows selected.
I ended up using this:
$result = $db->query($query)->fetchAll();
if (count($result) > 0) {
foreach ($result as $row) {
echo $row['blah'] . '<br />';
}
} else {
echo "<p>Nothing matched your query.</p>";
}
This post is old but Getting row count in php with PDO is simple
$stmt = $db->query('SELECT * FROM table');
$row_count = $stmt->rowCount();
This is super late, but I ran into the problem and I do this:
function countAll($table){
$dbh = dbConnect();
$sql = "select * from `$table`";
$stmt = $dbh->prepare($sql);
try { $stmt->execute();}
catch(PDOException $e){echo $e->getMessage();}
return $stmt->rowCount();
It's really simple, and easy. :)
This is an old post, but getting frustrated looking for alternatives. It is super unfortunate that PDO lacks this feature, especially as PHP and MySQL tend to go hand in hand.
There is an unfortunate flaw in using fetchColumn() as you can no longer use that result set (effectively) as the fetchColumn() moves the needle to the next row. So for example, if you have a result similar to
Fruit->Banana
Fruit->Apple
Fruit->Orange
If you use fetchColumn() you can find out that there are 3 fruits returned, but if you now loop through the result, you only have two columns, The price of fetchColumn() is the loss of the first column of results just to find out how many rows were returned. That leads to sloppy coding, and totally error ridden results if implemented.
So now, using fetchColumn() you have to implement and entirely new call and MySQL query just to get a fresh working result set. (which hopefully hasn't changed since your last query), I know, unlikely, but it can happen. Also, the overhead of dual queries on all row count validation. Which for this example is small, but parsing 2 million rows on a joined query, not a pleasant price to pay.
I love PHP and support everyone involved in its development as well as the community at large using PHP on a daily basis, but really hope this is addressed in future releases. This is 'really' my only complaint with PHP PDO, which otherwise is a great class.
Answering this because I trapped myself with it by now knowing this and maybe it will be useful.
Keep in mind that you cant fetch results twice. You have to save fetch result into array, get row count by count($array), and output results with foreach.
For example:
$query = "your_query_here";
$STH = $DBH->prepare($query);
$STH->execute();
$rows = $STH->fetchAll();
//all your results is in $rows array
$STH->setFetchMode(PDO::FETCH_ASSOC);
if (count($rows) > 0) {
foreach ($rows as $row) {
//output your rows
}
}
If you just want to get a count of rows (not the data) ie. using COUNT(*) in a prepared statement then all you need to do is retrieve the result and read the value:
$sql = "SELECT count(*) FROM `table` WHERE foo = bar";
$statement = $con->prepare($sql);
$statement->execute();
$count = $statement->fetch(PDO::FETCH_NUM); // Return array indexed by column number
return reset($count); // Resets array cursor and returns first value (the count)
Actually retrieving all the rows (data) to perform a simple count is a waste of resources. If the result set is large your server may choke on it.
Have a look at this link:
http://php.net/manual/en/pdostatement.rowcount.php
It is not recommended to use rowCount() in SELECT statements!
When it is matter of mysql how to count or get how many rows in a table with PHP PDO I use this
// count total number of rows
$query = "SELECT COUNT(*) as total_rows FROM sometable";
$stmt = $con->prepare($query);
// execute query
$stmt->execute();
// get total rows
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$total_rows = $row['total_rows'];
credits goes to Mike # codeofaninja.com
To use variables within a query you have to use bindValue() or bindParam(). And do not concatenate the variables with " . $variable . "
$statement = "SELECT count(account_id) FROM account
WHERE email = ? AND is_email_confirmed;";
$preparedStatement = $this->postgreSqlHandler->prepare($statement);
$preparedStatement->bindValue(1, $account->getEmail());
$preparedStatement->execute();
$numberRows= $preparedStatement->fetchColumn();
GL
A quick one liner to get the first entry returned. This is nice for very basic queries.
<?php
$count = current($db->query("select count(*) from table")->fetch());
?>
Reference
I tried $count = $stmt->rowCount(); with Oracle 11.2 and it did not work.
I decided to used a for loop as show below.
$count = "";
$stmt = $conn->prepare($sql);
$stmt->execute();
echo "<table border='1'>\n";
while($row = $stmt->fetch(PDO::FETCH_OBJ)) {
$count++;
echo "<tr>\n";
foreach ($row as $item) {
echo "<td class='td2'>".($item !== null ? htmlentities($item, ENT_QUOTES):" ")."</td>\n";
} //foreach ends
}// while ends
echo "</table>\n";
//echo " no of rows : ". oci_num_rows($stmt);
//equivalent in pdo::prepare statement
echo "no.of rows :".$count;
For straight queries where I want a specific row, and want to know if it was found, I use something like:
function fetchSpecificRow(&$myRecord) {
$myRecord = array();
$myQuery = "some sql...";
$stmt = $this->prepare($myQuery);
$stmt->execute(array($parm1, $parm2, ...));
if ($myRecord = $stmt->fetch(PDO::FETCH_ASSOC)) return 0;
return $myErrNum;
}
The simplest way, it is only 2 lines,
$sql = $db->query("SELECT COUNT(*) FROM tablename WHERE statement='condition'");
echo $sql->fetchColumn();
So, the other answers have established that rowCount() shouldn't be used to count the rows of a SELECT statement. The documentation even says, that :
PDOStatement::rowCount() returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement executed by the corresponding PDOStatement object.
https://web.archive.org/web/20220409162106/https://www.php.net/manual/en/pdostatement.rowcount.php
So it's okay for other queries, but not great for SELECT. Most answers suggest that you should make two queries, one to count rows, and one to get the subset of records you need. However, you could query the row count and your subset of the data in one request. This is a bit of an exercise in code golf, but could actually prove more efficient than two requests if the request time is a bit costly and these requests are made frequently.
If you're in PostgreSQL you can provide clean JSON output, like so:
WITH mytable as (VALUES(1,2,3),(4,5,6),(7,8,9),(10,11,12))
SELECT
jsonb_build_object(
'rowcount', (SELECT count(1) FROM mytable)
,'data', (
SELECT jsonb_agg(data.*)
FROM (
SELECT *
FROM mytable
WHERE column1 > 1 -- pagination offset
ORDER BY column1
LIMIT 2 -- page size
) as data
)
) jsondata
Output:
{"data": [
{
"column1": 4,
"column2": 5,
"column3": 6
},
{
"column1": 7,
"column2": 8,
"column3": 9
}
],
"rowcount": 4
}
If you're not in postgres, those functions won't be available, but you could do this:
WITH mytable as (VALUES(1,2,3),(4,5,6),(7,8,9),(10,11,12))
SELECT
(SELECT count(1) FROM mytable) as rowcount
,data.*
FROM (
SELECT *
FROM mytable as mytable(column1, column2, column3)
WHERE column1 > 1 -- pagination offset
ORDER BY column1
LIMIT 2 -- page size
) as data
but it will return the rowcount on every row, which might be a bit wasteful:
rowcount
column1
column2
column3
4
4
5
6
4
7
8
9
when you make a COUNT(*) in your mysql statement like in
$q = $db->query("SELECT COUNT(*) FROM ...");
your mysql query is already counting the number of result why counting again in php? to get the result of your mysql
$q = $db->query("SELECT COUNT(*) as counted FROM ...");
$nb = $q->fetch(PDO::FETCH_OBJ);
$nb = $nb->counted;
and $nb will contain the integer you have counted with your mysql statement
a bit long to write but fast to execute
Edit:
sorry for the wrong post but as some example show query with count in, I was suggesting using the mysql result, but if you don't use the count in sql fetchAll() is efficient, if you save the result in a variable you won't loose a line.
$data = $dbh->query("SELECT * FROM ...");
$table = $data->fetchAll(PDO::FETCH_OBJ);
count($table) will return the number of row and you can still use the result after like $row = $table[0] or using a foreach
foreach($table as $row){
print $row->id;
}
Here's a custom-made extension of the PDO class, with a helper function to retrieve the number of rows included by the last query's "WHERE" criteria.
You may need to add more 'handlers', though, depending on what commands you use. Right now it only works for queries that use "FROM " or "UPDATE ".
class PDO_V extends PDO
{
private $lastQuery = null;
public function query($query)
{
$this->lastQuery = $query;
return parent::query($query);
}
public function getLastQueryRowCount()
{
$lastQuery = $this->lastQuery;
$commandBeforeTableName = null;
if (strpos($lastQuery, 'FROM') !== false)
$commandBeforeTableName = 'FROM';
if (strpos($lastQuery, 'UPDATE') !== false)
$commandBeforeTableName = 'UPDATE';
$after = substr($lastQuery, strpos($lastQuery, $commandBeforeTableName) + (strlen($commandBeforeTableName) + 1));
$table = substr($after, 0, strpos($after, ' '));
$wherePart = substr($lastQuery, strpos($lastQuery, 'WHERE'));
$result = parent::query("SELECT COUNT(*) FROM $table " . $wherePart);
if ($result == null)
return 0;
return $result->fetchColumn();
}
}
You can combine the best method into one line or function, and have the new query auto-generated for you:
function getRowCount($q){
global $db;
return $db->query(preg_replace('/SELECT [A-Za-z,]+ FROM /i','SELECT count(*) FROM ',$q))->fetchColumn();
}
$numRows = getRowCount($query);
There is a simple solution. If you use PDO connect to your DB like this:
try {
$handler = new PDO('mysql:host=localhost;dbname=name_of_your_db', 'your_login', 'your_password');
$handler -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo $e->getMessage();
}
Now, if you want to know how many rows are existing in your table and you have for example column 'id' as the primary key, the query to DB will be:
$query = $handler->query("SELECT id FROM your_table_name");
And finally, to get the amount of the rows matching your query, write like this:
$amountOfRows = $query->rowCount();
Or you can write:
$query = $handler ->query("SELECT COUNT(id) FROM your_table_name");
$amountOfRows = $query->rowCount();
Or, if you want to know how many products there are in the table 'products' have the price between 10 and 20, write this query:
$query = $handler ->query("SELECT id FROM products WHERE price BETWEEN 10 AND
20");
$amountOfRows = $query->rowCount();

php sql multiple queries into one

Part of my page I have lots of small little queries, probably about 6 altogether, grabbing data from different tables. As an example:
$sql_result = mysql_query("SELECT * FROM votes WHERE voted_on='$p_id' AND vote=1", $db);
$votes_up = mysql_num_rows($sql_result);
$sql_result = mysql_query("SELECT * FROM votes WHERE voted_on='$p_id' AND vote=0", $db);
$votes_down = mysql_num_rows($sql_result);
$sql_result = mysql_query("SELECT * FROM kids WHERE (mother_id='$p_id' OR father_id='$p_id')", $db);
$kids = mysql_num_rows($sql_result);
Would it be better if these were all grabbed in one query to save trips to the database? One query is better than 6 isn't it?
Would it be some kind of JOIN or UNION?
Its not about number of queries but amount of useful datas you transfer. If you are running database on localhost, is better to let sql engine to solve queries instead computing results in additional programs. The same if you are thinking about who should be more bussy. Apache or mysql :)
Of course you can use some conditions:
SELECT catName,
SUM(IF(titles.langID=1, 1, 0)) AS english,
SUM(IF(titles.langID=2, 1, 0)) AS deutsch,
SUM(IF(titles.langID=3, 1, 0)) AS svensk,
SUM(IF(titles.langID=4, 1, 0)) AS norsk,
COUNT(*)
FROM titles, categories, languages
WHERE titles.catID = categories.catID
AND titles.langID = languages.
example used from MYSQL Bible :)
If you really want to lower the number of queries, you can put the first two together like this:
$sql_result = mysql_query("SELECT * FROM votes WHERE voted_on='$p_id'", $db);
while ($row = mysql_fetch_array($sql_result))
{
extract($row);
if ($vote=='0') ++$votes_up; else ++$votes_down;
}
The idea of joining tables is that these tables are expected to have something in between (a relation, for example).
Same is for the UNION SELECTS, which are prefered to be avoided.
If you want your solution to be clean and scalable in future, I suggest you to use mysqli, instead of mysql module of PHP.
Refer to: mysqli::multi_query. There is OOP variant, where you create mysqli object and call the function as method.
Then, your query should look like:
// I use ; as the default separator of queries, but it might be different in your case.
// The above could be set with sql statement: DELIMITER ;
$query = "
SELECT * FROM votes WHERE voted_on='$p_id' AND vote=1;
SELECT * FROM votes WHERE voted_on='$p_id' AND vote=0;
SELECT * FROM kids WHERE (mother_id='$p_id' OR father_id='$p_id');
";
$results = mysqli_multi_query($db, $query); // Returns an array of results
Fewer queries are (generally, not always) better, but it's also about keeping your code clear enough that others can understand the query. For example, in the code you provided, keep the first two together, and leave the last one separate.
$sql_result = mysql_query("SELECT vote, COUNT(*) AS vote_count
FROM votes
WHERE voted_on='$p_id'
GROUP BY vote", $db);
The above will return to you two rows, each containing the vote value (0 or 1) and the vote count for the value.

Subquery in PHP

Let's put an easy example with two tables:
USERS (Id, Name, City)
PLAYERS (Id_Player, Number, Team)
And I have to do a query with a subselect in a loop, where the subselect is always the same, so I would like to divide it into two queries and put the subselect outside the loop.
I explain. What works but it is not optimize:
for($i=0;$i<something;$i++)
{
$res2=mysql_query("SELECT Team from PLAYERS WHERE Number=$i
AND Id_Player IN (SELECT Id FROM USERS WHERE City='London')");
}
What I would like to do but it doesn't work:
$res1=mysql_query("SELECT Id from USERS where City='London'");
for($i=0;$i<something;$i++)
{
$res2=mysql_query("SELECT Team from PLAYERS WHERE Number=$i
AND Id_Player IN **$res1**");
}
Thanks!
Something like this should work.
<?
$sql = "SELECT Team from PLAYERS
JOIN USERS on (Id_player=Id)
WHERE Number BETWEEN $minID AND $maxID
AND City='London'
GROUP BY Team";
$results=mysql_query($sql) or die(mysql_error());
// $results contain all the teams from London
// Use like normal..
echo "<ul>\n";
while($team = mysql_fetch_array($results)){
echo "\t<li>{$team['Team']}</li>\n";
}
echo "</ul>";
Placing SQL quires in loops can be very slow and take up a lot of resources, have a look at using JOIN in you SQL. It's not that difficult and once you've got the hang of it you can write some really fast powerful SQL.
Here is a good tutorial worth having a look at about the different types of JOINs:
http://www.keithjbrown.co.uk/vworks/mysql/mysql_p5.php
SELECT PLAYERS.*, USERS.City FROM PLAYERS, USERS WHERE USERS.City='London' AND PLAYERS.Number = $i
Not the best way to do it; maybe a LEFT JOIN, but it should work. Might have the syntax wrong though.
James
EDIT
WARNING: This is not the most ideal solution. Please give me a more specific query and I can sort out a join query for you.
Taking your comment into account, let's take a look at another example. This will use PHP to make a list we can use with the MySQL IN keyword.
First, make your query:
$res1 = mysql_query("SELECT Id from USERS where City='London'");
Then, loop through your query and put each Id field one after another in a comma seperated list:
$player_ids = "";
while($row = mysql_fetch_array($res1))
{
$player_ids .= $row['Id'] . ",";
}
$player_ids = rtrim($player_ids, ",");
You should now have a list of IDs like this:
12, 14, 6, 4, 3, 15, ...
Now to put it into your second query:
for($i = 0; $i<something; $i++)
{
$res2 = mysql_query("SELECT Team from PLAYERS WHERE Number=$i
AND Id_Player IN $player_ids");
}
The example given here can be improved for it's specific purpose, however I'm trying to keep it as open as possible.
If you want to make a list of strings, not IDs or other numbers, modify the first while loop, replacing the line inside it with
$player_ids .= "'" . $row['Id'] . "',";
If you could give me your actual query you use, I can come up with something better; as I said above, this is a more generic way of doing things, not necessarily the best.
Running query in a loop is not a great idea. Much better would be to get whole table, and then iterate through table in loop.
So query would be something like that:
"SELECT Team from PLAYERS WHERE Number BETWEEN($id, $something)
AND Id_Player IN (SELECT Id FROM USERS WHERE City='London')"
$res1=mysql_query("SELECT Id from USERS where City='London'");
for($i=0;$i<something;$i++)
{
$res2=mysql_query("SELECT Team from PLAYERS WHERE Number=$i
AND Id_Player IN **$res1**");
}
Would work, but mysql_query() returns a RESULT HANDLE. It does not return the id value. Any select query, no matter how many, or few, rows it returns, returns a result statement, not a value. You first have to fetch the row using one of the mysql_fetch...() calls, which returns that row, from which you can then extract the id value. so...
$stmt = mysql_query("select ID ...");
if ($stmt === FALSE) {
die(msyql_error());
}
if ($stmt->num_rows > 0) {
$ids = array();
while($row = mysql_fetch_assoc($stmt)) {
$ids[] = $row['id']
}
$ids = implode(',', $ids)
$stmt = mysql_query("select TEAM from ... where Id_player IN ($ids)");
.... more fetching/processing here ...
}

Categories