PHP, MYSQL: Select inside a while Loop? - php

I am requesting your advice about the following:
I have two tables:
Customers and Orders.
I am printing the data of customers inside a table using a while loop:
$sql = "SELECT * FROM wccrm_customers where status = '1' order by date desc";
$result = mysql_query($sql, $db);
while ($daten = mysql_fetch_array($result)) { ?>
echo $daten[id];
echo $daten[name] . ' ' . $daten[vorname];
echo $daten[email];
echo $daten[telefon];
} ?>
Now I try to add a new field in this list: Purchased YES/NO. As we have more customers then buyers, we want to show whether someone has bought or not:
The Connection between this two tables is the first/lastname in both tables!
So if customer.name = orders.name and customer.firstname = orders.firstname I want to echo "YES" if not then "NO"
I tried with a JOIN, but here I just get the results who are in both table:
SELECT *
FROM wccrm_customers AS k
INNER JOIN wccrm_orders AS o
ON o.namee = k.name AND o.firstname = k.firstname
but I need to have all of the customers and the ones who are in both lists marked...
Is this possible? If yes: How can I achieve this?
Thank's for your advice!
Kind regards,
Stefan

This has nothing to do with PHP, or with while loops; you just need to form your join properly:
SELECT DISTINCT
`k`.*,
`o`.`namee` IS NOT NULL AS `Purchased`
FROM `wccrm_customers` AS `k`
LEFT JOIN `wccrm_orders` AS `o`
ON
`o`.`namee` = `k`.`name`
AND `o`.`firstname` = `k`.`firstname`
Read more about the different join types: http://www.sql-join.com/sql-join-types/
(images courtesy of that site, which also contains an example and discussion of almost exactly what you're trying to do!)
By the way, you must have missed the massive red warning banner in the manual about using the deprecated (now removed) mysql_* functions. You should stop doing that! Use MySQLi or PDO instead.

a shorter one
SELECT DISTINCT k.*, IF(o.namee IS NULL, 'no', 'yes') purchased
FROM
wccrm_customers AS k
LEFT JOIN wccrm_orders AS o USING (namee,firstname)

Related

Only the last record from the database is displayed

I connected, I created a quick script in which I want to manage clients, domains and notes.
The problem is that when I add 2 notes to the client from ID: 1 - after viewing I see only one.
The following code shows what I have done so far
SQL Query:
$sql = "SELECT * FROM domain JOIN note ON domain.id = note.domain_id GROUP BY domain.id";
My PHP code:
while($rs = $resultdb->fetch_array(MYSQLI_ASSOC)) {
echo '<tr>';
echo '<td>'.$rs["id"].'</td>';
echo '<td><strong>'.$rs["domain_name"].'</strong></td>';
echo '<td>'.$rs["note"].'</td>';
echo '</tr>';
}
The result he gets is:
ID DOMAIN NOTE
1 "domain1.com" "note 1 to domain1.com"
2 "domain2.com" "note 2 to domain2.com"
However, in the database I have added a few notes to domain1.com.
I would like to see all the notes added to a given domain.
EDIT:
When I do: "SELECT * FROM domain JOIN note ON domain.id = note.domain_id";
I getting:
I getting
I expect
EDIT: Add screnshot
LEFT JOIN
Your GROUP BY is limiting the records retrieved by the query. If you want all of the notes together you can try using GROUP_CONCAT() to produce a single field with all of the notes in one...
$sql = "SELECT domain.id as id, domain.domain_name as domain_name,
GROUP_CONCAT(note.note) as note
FROM domain
LEFT JOIN note ON domain.id = note.domain_id
GROUP BY domain.id";
You might also change the JOIN to LEFT JOIN in case there are no notes for a particular domain.
Probably you need to use a separate query to get "Domain Notes" in the while. for example:
while ($rs = $resultdb->fetch_array(MYSQLI_ASSOC)) {
$sql_notes = "SELECT * FROM notes WHERE domain_id = '" . (int)$rs['domain_id'] . "'";
...
}
you need group_concat group by note.domain_id
if you need exact match the use inner join
"SELECT id, domain, group_concat(note) as note
FROM domain
INNER JOIN note ON domain.id = note.domain_id
GROUP BY note.domain_id";
if you needc result also for id without notes then try
"SELECT id, domain, (group_concat(ifnull(note,'')) as note
FROM domain
LEFT JOIN note ON domain.id = note.domain_id
GROUP BY note.domain_id";

MYSQL query so it also returns values if has no value in the other table

Hi guys in the code below you can see what my JSON returns.
{"lifehacks":[{
"id":"2",
"URLtoImage":"http:\/\/images.visitcanberra.com.au\/images\/canberra_hero_image.jpg",
"title":"dit is nog een test",
"author":"1232123",
"score":"2",
"steps":"fdaddaadadafdaaddadaaddaadaaaaaaaaaaa","category":"Category_2"}]}
What the JSON returns is fine. The only problem is it is only displaying lifehacks if it has one like or more. So what should I change about my Query so it would display lifehacks without likes aswell.
//Select the Database
mysql_select_db("admin_nakeitez",$db);
//Replace * in the query with the column names.
$result = mysql_query("select idLifehack, urlToImage, title, Lifehack.Users_fbId, idLifehack, steps, Categorie, count(Lifehack_idLifehack) as likes from Lifehack, Likes where idLifehack = Lifehack_idLifehack AND idLifehack > " . $_GET["id"]. " group by idLifehack;", $db);
//Create an array
$json_response = array();
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
$row_array['id'] = $row['idLifehack'];
$row_array['URLtoImage'] = $row['urlToImage'];
$row_array['title'] = $row['title'];
$row_array['author'] = $row['Users_fbId'];
$row_array['score'] = $row['likes'];
$row_array['steps'] = $row['steps'];
$row_array['category'] = $row['Categorie'];
//push the values in the array
array_push($json_response,$row_array);
}
echo "{\"lifehacks\":";
echo json_encode($json_response);
echo "}";
//Close the database connection
fclose($db);
I hope my problem is clear like this. Thank you in advance I can't figure it out myself.
You need a LEFT JOIN here. Your query has an INNER JOIN.
select
idLifehack,
urlToImage,
title,
Lifehack.Users_fbId,
idLifehack,
steps,
Categorie,
count(Lifehack_idLifehack) as likes
from Lifehack
left join Likes on idLifehack = Lifehack_idLifehack
where idLifehack > whatever
group by idLifehack;
There's an excellent explanation of the different join types here.
A couple additional points...
Use prepared statements in your PHP. Your code is wide-open to SQL Injection, which has ruined careers and led to millions of innocent people having their personal information stolen. There are plenty of web sites showing how to do this so I won't go into it here, though I'll say my favorite is bobby-tables.
Avoid the implicit join anti-pattern in your queries. This is an implicit join:
FROM a, b
WHERE a.id = b.id
Use explicit joins instead; they separate your join logic from your filtering (WHERE) logic:
FROM a
INNER JOIN b ON a.id = b.id

Foreach looping too many times

I'm using this to display information from a queried db in Wordpress. It displays the correct information but it loops it too many times. It is set to display from a SELECT query and depending on the last entry to the db seems to be whether or not it prints double or triple each entry.
foreach ($result as $row) {
echo '<h5><i>'.$row->company.'</i> can perform your window installation for <i>$'.$row->cost.'</i><br>';
echo 'This price includes using<i> '.$row->material.'</i> as your material(s)<br>';
echo '<hr></h5>';
}
Does anyone know what could be producing this error?
Thanks
The query powering that script is:
$result = $wpdb->get_results( "SELECT bp.*, b.company
FROM `windows_brands_products` bp
LEFT JOIN `windows_brands` b
ON bp.brand_id = b.id
JOIN Windows_last_submissions ls
JOIN windows_materials wm
JOIN Windows_submissions ws
WHERE ws.username = '$current_user->user_login'
AND bp.width = ROUND(ls.width)
AND bp.height = ROUND(ls.height)
AND bp.material IN (wm.name)
AND bp.type = ls.type
AND IF (ls.minimumbid != '0.00',bp.cost BETWEEN ls.minimumbid AND ls.maximumbid,bp.cost <= ls.maximumbid)
ORDER BY b.company ASC");
I can't seem to see the duplicate but I agree it must be there.
EDIT-- when I replace the WHERE clause to WHERE ws.username = 'password' , it still repeats. It it displaying a result for each time a result has username='password' , and displaying that set twice as well.
I think you want the following, if you're using MySQLi:
while ($row = $result->fetch_object()) {
echo '<h5><i>'.$row->company.'</i> can perform your window installation for <i>$'.$row->cost.'</i><br>';
echo 'This price includes using<i> '.$row->material.'</i> as your material(s)<br>';
echo '<hr></h5>';
}
Redundant JOIN clauses in my query which was pretty much pulling the same results from two tables (one of which was just a VIEW of the other).

how to solve this mysql query

I have 3 mysql tables
user(u_id(p),name),
team(t_id(p),u_id(f),t_name,t_money,days_money) and
history(t_id(f),day,d_money).
Now I have to display leaderboard using php.
I tried this.
SELECT t_id FROM team;
got result.
then,
in for loop
foreach($tid_all as $tid)
{
$que = $db_con->prepare("SELECT d_money, t_name FROM team, history WHERE t_id= '".$tid['t_id']."' && day='1'");
$que->execute();
while($info = $que->fetch(PDO::FETCH_NUM))
{
echo "<tr>";
echo "<td>".$info[0]."</td>";
echo "<td>".$info[1]."</td>";
echo "</tr>";
}
}
but it didnt work. any solution?
Solution 1:
i tried this and it worked.
`SELECT d_money, t_name FROM team, history WHERE history.t_id=$tid['t_id'] AND team.t_id=history.t_id`
is it correct way or not?
thanks everyone for help.
Question : is it possible to order the result table by d_money? i want it in descending order.
Replace && with AND.Try like this :
"SELECT d_money, t_name FROM team, history WHERE t_id= '".$tid['t_id']."' AND day='1' order by d_money DESC "
There is no && in MySQL Query. Replace that with AND Operator on your query.
Since you want to get the data from the two tables, then JOIN the two tables instead of doing that with a loop:
SELECT
h.d_money,
t.t_name
FROM team AS t
INNER JOIN history AS h ON t.t_id = h.t_id;
Run this single query once and you will get what you want. You can also add a WHERE clause at the end of it the way you did in your query.
try this
SELECT d_money, t_name FROM team, history WHERE team.t_id= '".$tid['t_id']."' AND history.t_id= '".$tid['t_id']."' && day='1'
Can you replace
WHERE t_id= '".$tid."' AND day='1'
instead of
WHERE t_id= '".$tid['t_id']."' && day='1'

why i can't display my records in php mysql?

I have records in my database but I can't display them. Can someone check my codes, please. I'm just an amateur web developer. Thanks for any help.
<?php
$groups=mysql_query("SELECT * FROM groups ORDER BY id ASC");
$g_res=mysql_affected_rows();
if($g_res>0)
{
while($row=mysql_fetch_array($groups))
{
$g_id=$row['id'];
$g_name=$row['g_name'];
$members=mysql_query("SELECT * FROM members WHERE group='$g_id'");
$m_res=mysql_affected_rows();
if($m_res>0)
{
while($row2=mysql_fetch_array($members))
{
$m_id=$row2['id'];
$m_name=$row2['m_name'];
$m_email=$row2['m_email'];
echo "<tr><td>$m_name<br/>($g_name)</td><td>$m_email</td></tr>";
}
}
else
{
echo "<tr><td colspan=2>Nothing to display</td></tr>";
}
}
}
else
{
echo "<tr><td colspan=2>Error</td></tr>";
}
?>
With this code I get the else result which is Error. If I remove WHERE group='$g_id' from the query, all of my records are displayed randomly, but I'd like to show my records (members) by group.
You need to escape reserved words in MySQL like group with backticks
SELECT * FROM members WHERE `group` = '$g_id'
^-----^-------------here
You can also spare the inner loop when you join your data like this
select g.id as gid, g.g_name, m.id as mid, m.m_name, m.m_email
from groups g
inner join members m on g.id = m.group
order by g.id asc
This is easier and will increase performance since you don't need to execute a lot of queries but just one.
Also please don't use mysql_* functions in new code.
They are no longer maintained and are officially deprecated.
Learn about Prepared Statements instead, and use PDO or MySQLi. See this article for a quick overview how to do it and why it is so important.
Try like
$members=mysql_query("SELECT * FROM members WHERE `group` = '".$g_id."');
or simply
$members=mysql_query("SELECT * FROM members WHERE `group` = '$g_id'");
You have to concatenate your variables.
Try this:
$members=mysql_query("SELECT * FROM members WHERE `group`='".$g_id."'");
And
echo "<tr><td>".$m_name."<br/>(".$g_name.")</td><td>".$m_email."</td></tr>";

Categories