I have 2 tables, comments and gossips.
Gossips has 3 columns: id, userid, gossip.
Comments has 4 columns: id, userid, gossipid, comment.
I wrote this code so that the program echos all the gossips and the comments specific to each gossip.
$query = 'SELECT * FROM gossips ORDER BY id DESC LIMIT 0,10';
$result = mysqli_query($cxn, $query)
or die("Couldn't execute query");
while($row = mysqli_fetch_assoc($result))
{
echo '<div class="gossip">'.$row['gossip'].'</div><form action="comment.php" method="post"><input type="hidden" name="gossipid" value="'.$row['id'].'" />';
echo '<input type="text" name="comment" placeholder="Write your comment here"/><br /><input type="submit" value="Comment" /></form><br />';
$querycomment = "SELECT * FROM comment WHERE gossipid ='{$row['id']}' ORDER BY id DESC";
$resultcomment = mysqli_query($cxn, $query)
or die("Couldn't fetch comments.");
while($comments = mysqli_fetch_assoc($resultcomment))
{
echo $comments['comment'];
}
}
The output of this code is only echoing the gossips and isn't executing the second while loop. What could be the problem ?
You go through the entire $resultcomment result set the first time you go around that loop. When the SECOND iteration of the outer $result loop starts up, there's no more data to be fetched from that second query, so in effect the inner loop only ever runs for that FIRST record from the $result set.
Since you seem to be filtering the inner loop's results using the outer loop's data, why not base that inner query on the same data, so you don't suck across your entire comment table and throw away everything EXCEPT for the matching records? That's a hideous waste.
Something more like
SELECT * FROM gossips
while(fetch gossip) {
SELECT * FROM comment WHERE id = gossip.id
}
This is somewhat more efficient, since you fetch only the comments you'd actually want to display. A further optimization would be to rewrite both queries as a single JOIN query, with some looping logic to detect when you change between gossips.
Related
I'm totally stuck! I need to create navigation buttons in order to go through records that match a specific Id. So far I have only been able to retrieve 1 record (the first one). I am using the following code to do so:
$query = "SELECT t1.requester_name, t1.requester_email, t1.client_name, t1.client_country, t1.machine_quantity, t1.severity, t1.sales_connect, t1.request_status, t2.serial_type, t2.serial_model, t2.serial_number, t2.machine_status, t2.machine_config, t2.brand, t2.tier, t2.request_id
FROM requests t1
LEFT JOIN serialnumbers t2
ON t1.request_id = t2.request_id
WHERE t1.request_id = {$id} ";
$results = mysql_query($query, $connection);
$row = mysql_fetch_assoc($results);
The records are coming from 2 distinct tables and while I am having no trouble with the Request Table (Always one row), I cannot manage to figure out how to get every row in the Serial Numbers table (one to many relationship).
I am using a html form to display these values... Here is a sample of how I am doing so:
<input type="text" value="<?php echo $row['serial_type']; ?>" id="machineType" name="machineType[]" />
Any ideas on how I can achieve this objective?
you are going to want to make your $row = mysql_fetch_assoc a while loop.
while ($row = mysql_fetch_assoc($results)){
echo '<input type="text" value="'.$row['serial-type']." id="machineType" name="machineType[]" />';
}
something along those lines.
I have 2 tables in the database, the table circle and the table gossips.
The table circle has 3 columns: id, idfrom, idto.
The table gossips has id, userid, gossip.
My objectif is to echo all the gossips only if the userid of this gossip (idto) and the id of the pageuser(idfrom) are on the same row in the table circle.
I wrote this code,
$query = 'SELECT * FROM gossips ORDER BY id DESC';
$result = mysqli_query($cxn, $query)
or die("Couldn't execute query");
$querycircle = 'SELECT idfrom,idto FROM circle WHERE idfrom="{$pageuserid}" ';
$resultcircle = mysqli_query($cxn, $querycircle)
or die("Couldn't check if user in circle.");
while($row = mysqli_fetch_assoc($result))
{
while($rowcheck = mysqli_fetch_assoc($resultcircle))
{
if($row['userid'] == $rowcheck['idto'] || $row['userid'] == $_COOKIE['id']){
echo '<div class="gossip">'.$row['gossip'].'</div>';
}
}
}
But it doesn't seem to work properly.
Do you intend to get the same data with mysqli_fetch_assoc($resultcircle)) on each round of the first while-loop?
Then you should buffer this data in an array first, as executing mysqli_fetch_assoc will always give you the next data set on each successive call. It will not restart on top of the data.
(Btw, this is better: while(null !== ($rowcheck = mysqli_fetch_assoc($result))))
Another method to realize your objective is to do only one combined SQL request.
EDIT: Sudip Pal is fast, look at his answer for a combined request! ;)
Try the single SQL query for this and then try with one while loop.
Select A.gossip from gossips A, circle B where A.userid=B.idto and B.idfrom="{$pageuserid}" order by A.id DESC;
NOTE: you can also compare the COOKIE value by adding the extra comparison on the query, like and B.userid=$_COOKIE["id"] (better to save the cookie value in a variable)
I have 2 tables, comments and gossips.
Gossips has 3 columns: id, userid, gossip.
Comments has 4 columns: id, userid, gossipid, comment.
I wrote this code so that the program echos all the gossips and the comments specific to each gossip.
$query = 'SELECT * FROM gossips ORDER BY id DESC LIMIT 0,10';
$result = mysqli_query($cxn, $query)
or die("Couldn't execute query");
while($row = mysqli_fetch_assoc($result))
{
echo '<div class="gossip">'.$row['gossip'].'</div><form action="comment.php" method="post"><input type="hidden" name="gossipid" value="'.$row['id'].'" />';
echo '<input type="text" name="comment" placeholder="Write your comment here"/><br /><input type="submit" value="Comment" /></form><br />';
$querycomment = "SELECT * FROM comment WHERE gossipid ='{$row['id']}' ORDER BY id DESC";
$resultcomment = mysqli_query($cxn, $query)
or die("Couldn't fetch comments.");
while($comments = mysqli_fetch_assoc($resultcomment))
{
echo $comments['comment'];
}
}
The output of this code is only echoing the gossips and isn't executing the second while loop. What could be the problem ?
You go through the entire $resultcomment result set the first time you go around that loop. When the SECOND iteration of the outer $result loop starts up, there's no more data to be fetched from that second query, so in effect the inner loop only ever runs for that FIRST record from the $result set.
Since you seem to be filtering the inner loop's results using the outer loop's data, why not base that inner query on the same data, so you don't suck across your entire comment table and throw away everything EXCEPT for the matching records? That's a hideous waste.
Something more like
SELECT * FROM gossips
while(fetch gossip) {
SELECT * FROM comment WHERE id = gossip.id
}
This is somewhat more efficient, since you fetch only the comments you'd actually want to display. A further optimization would be to rewrite both queries as a single JOIN query, with some looping logic to detect when you change between gossips.
I'm probably missing something obvious but when I try to execute this query, it returns no results. I plugged it directly into MySQL and also tried replacing the variable with a valid row value and I get the correct output. When I use a variable, it gives me no results. Anyone have any thoughs?
$query = "SELECT title FROM le7dm_pf_tasks WHERE project = (SELECT id FROM le7dm_pf_projects WHERE title = '".$ws_title."') ORDER BY title DESC LIMIT 1";
$result_query = mysql_query($query) or die("Error: ".mysql_error());
while ($row = mysql_fetch_assoc($result_query)) {
$result_title = $row['title'];
}
$result_title = substr($result_title,0,6);
echo $result_title;
Your SQL could do with some rework (though not the reason for your issue). No need for the nested select (which can also cause an error if it returns > 1 row). Try a join.
$sql = "
SELECT title FROM le7dm_pf_tasks t
INNER JOIN le7dm_pf_projects p ON t.project = p.id
WHERE p.title = '{$ws_title}'
ORDER BY title DESC LIMIT 1
";
You are also iterating over an unknown number of rows using the while statement. And then you exit and attempt a substring. How do you know that the last row iterated in the while had a value.
Try outputting $result_title inside the while loop itself to confirm data.
echo $result_title;
If you truly only have a single row, there is no need for the while loop. Just do
$row = mysql_fetch_assoc($result_query);
strip_tags($ws_title); - is what did it! The title was wrapped in an anchor tag that linked to that particular project page.
Thanks for all the good suggestions though. I'm gonna use some of them in the future when bug testing.
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 ...
}