Only the last record from the database is displayed - php

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";

Related

Showing two different values depending on SESSION value in INNER JOIN

I have two different tables, one named users, and another named transactions. Transactions contains wallet1, wallet2, amount. Users contains user details such as firstname, lastname, and wallet. I am trying to display the corresponding first name and last name, depending on whether or not the SESSION_wallet is equal to wallet1 or wallet2 within transactions. I tried searching for a while, and came up with a solution for showing the correct display name for the first and last name making the transfer, however, I am trying to make it display the correct value for "Transfer to:"
Here is some of my code to get a better understanding of what I mean:
MySQLi Query:
$result2 = mysqli_query($link, "SELECT * FROM transactions INNER JOIN users ON transactions.wallet1 = users.wallet WHERE transactions.wallet1 = '" . $_SESSION["wallet"] . "' OR transactions.wallet2 = '" . $_SESSION["wallet"] . "' Order by transactions.id DESC LIMIT 5 ");
PHP Code:
<?php
if(mysqli_num_rows($result2) > 0)
{
while($row = mysqli_fetch_array($result2))
{
?>
The table that needs to display the transfer from, and transfer to:
<?php
if ($_SESSION["wallet"] == $row["wallet1"]) {
echo "<td>Transfer to ".$row["firstname"]." ".$row["lastname"]."</td>";
}
else if ($_SESSION["wallet"] == $row["wallet2"]) {
echo "<td>Transfer from ".$row["firstname"]." ".$row["lastname"]."</td>";
}
?>
Right now my tables are only showing the first and last name of the user that made the Transfer, however, I need it to display the first and last name of the user that the transaction is made to as well. The else if code is working correct, but the first part is not showing the corresponding value.
You will need to JOIN your transactions table to your users table twice, once to get each users name. Then to avoid duplicate column names overwriting the results in the output array, you will need to use column aliases. Something like this should work:
$result2 = mysqli_query($link, "SELECT t.*,
u1.firstname AS w1_firstname,
u1.lastname AS w1_lastname,
u2.firstname AS w2_firstname,
u2.lastname AS w2_lastname
FROM transactions t
INNER JOIN users u1 ON t.wallet1 = u1.wallet
INNER JOIN users u2 ON t.wallet2 = u2.wallet
WHERE t.wallet1 = '{$_SESSION["wallet"]}'
OR t.wallet2 = '{$_SESSION["wallet"]}'
ORDER BY t.id DESC
LIMIT 5 ");
Then you can access each user's names as $row['w1_firstname'] etc.:
if ($_SESSION["wallet"] == $row["wallet1"]) {
echo "<td>Transfer to ".$row["w2_firstname"]." ".$row["w2_lastname"]."</td>";
}
else if ($_SESSION["wallet"] == $row["wallet2"]) {
echo "<td>Transfer from ".$row["w1_firstname"]." ".$row["w1_lastname"]."</td>";
}
Note that ideally you should use a prepared query for this, for example:
$stmt = $link->prepare("SELECT t.*,
u1.firstname AS w1_firstname,
u1.lastname AS w1_lastname,
u2.firstname AS w2_firstname,
u2.lastname AS w2_lastname
FROM transactions t
INNER JOIN users u1 ON t.wallet1 = u1.wallet
INNER JOIN users u2 ON t.wallet2 = u2.wallet
WHERE t.wallet1 = ?
OR t.wallet2 = ?
ORDER BY t.id DESC
LIMIT 5");
$stmt->bind_param('ss', $_SESSION["wallet"], $_SESSION["wallet"]);
$stmt->execute();
$result2 = $stmt->get_result();

MYSQL - GROUP BY - PHP query

Hello the group by on MYSQL is working but on PHP query i not working.
If i remove Group By from PHP is working but i dont take correct results.
MYSQL
SELECT _o.Ora,_u.Fname,_u.Sname,_u.Phone,_o.Name1,_o.Name2,_o.Name3,_o.Name4,_o.Name5,_o.Name6,_o.PaymentType,_o.FinalPrice
FROM _orders as _o,_users as _u WHERE _o.ShopName='ISAAK' AND _o.HmerominiaParagelias='13/12/2018' AND _o.UserID=_u.Username
GROUP BY _o.OraParagelias IN (SELECT MAX(OraParagelias) FROM _orders) ORDER BY _o.Ora DESC;
Result
PHP Code:
<?php
include_once 'connect.php';
$ShopName= $_POST['ShopName'];
$HmerominiaParagelias= $_POST['HmerominiaParagelias'];
$sql = "SELECT _o.Ora,_u.Fname,_u.Sname,_u.Phone,_o.Name1,_o.Name2,_o.Name3,_o.Name4,_o.Name5,_o.Name6,_o.PaymentType,_o.FinalPrice
FROM _orders as _o,_users as _u WHERE _o.ShopName='$ShopName' AND _o.HmerominiaParagelias='$HmerominiaParagelias' AND _o.UserID=_u.Username
GROUP BY _o.OraParagelias IN (SELECT MAX(OraParagelias) FROM _orders) ORDER BY _o.Ora DESC";
$result = $dbcon->query($sql);
if($result->num_rows> 0) {
while ($row = $result->fetch_assoc()){
echo "\nΏρα: ".$row["Ora"]."\nΌνομα: ".$row["Fname"]."\nΕπώνυμο: ".$row["Sname"]."\nΤηλ.: ".$row["Phone"]."\n".$row["Name1"]."\n".$row["Name2"]."\n".
$row["Name3"]."\n".$row["Name4"]."\n".$row["Name5"]."\n".$row["Name6"]."\nΤρόπος Πλήρ.: ".$row["PaymentType"]."\nΤελικό Ποσό: ".$row["FinalPrice"].
"€?";
}
} else{
echo "no_orders_found?";
}
?>
[![enter image description here]
As result i take: no_orders_found
Any solution on how to fix group by on php?
Consider a compliant ANSI SQL query using explicit JOIN between tables. Specifically, join on an aggregate query to connect user unit level data to their corresponding max value to return more than two users. Below assumes UserID is the unique value to use for joining (adjust as needed).
Likely, the reason for differences of query runs is the PHP DBI-API (mysqli, pdo, etc.) does not allow the strange (newer?) GROUP BY ... IN() whereas MySQL workbench apparently does, maybe with a specific setting turned on.
SELECT _o.Ora, _u.Fname, _u.Sname, _u.Phone, _o.Name1, _o.Name2, _o.Name3,
_o.Name4, _o.Name5, _o.Name6, _o.PaymentType, _o.FinalPrice
FROM _orders as _o,
INNER JOIN _users as _u
ON _o.UserID = _u.Username
INNER JOIN
(SELECT UserID, MAX(OraParagelias) AS Max_OraParagelias
FROM _orders
GROUP BY userID
) AS m
ON _o.userID = m.userID AND _o.OraParagelias = m.Max_OraParagelias
WHERE _o.ShopName = 'ISAAK'
AND _o.HmerominiaParagelias = '13/12/2018'
ORDER BY _o.Ora DESC;
Rextester Demo (using sample data)

PHP, MYSQL: Select inside a while Loop?

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)

Inner/Left join with two different where clauses

i'm in the process of joining two tables together under two different conditions. For primary example, lets say I have the following nested query:
$Query = $DB->prepare("SELECT ID, Name FROM modifications
WHERE TYPE =1 & WFAbility = '0'");
$Query->execute();
$Query->bind_result($Mod_ID,$Mod_Name);
and this query:
$Query= $DB->prepare("SELECT `ModID` from `wfabilities` WHERE `WFID`=?");
$Query->bind_param();
$Query->execute();
$Query->bind_result();
while ($Query->fetch()){ }
Basically, I want to select all the elements where type is equal to one and Ability is equal to 0, this is to be selected from the modifications table.
I further need to select all the IDs from wfabilities, but transform them into the names located in modifications where WFID is equal to the results from another query.
Here is my current semi-working code.
$Get_ID = $DB->prepare("SELECT ID FROM warframes WHERE Name=?");
$Get_ID->bind_param('s',$_GET['Frame']);
$Get_ID->execute();
$Get_ID->bind_result($FrameID);
$Get_ID->fetch();
$Get_ID->close();
echo $FrameID;
$WF_Abilties = $DB->prepare("SELECT ModID FROM `wfabilities` WHERE WFID=?");
$WF_Abilties->bind_param('i',$FrameID);
$WF_Abilties->execute();
$WF_Abilties->bind_result($ModID);
$Mod_IDArr = array();
while ($WF_Abilties->fetch()){
$Mod_IDArr[] = $ModID;
}
print_r($Mod_IDArr);
$Ability_Name = array();
foreach ($Mod_IDArr AS $AbilityMods){
$WF_AbName = $DB->prepare("SELECT `Name` FROM `modifications` WHERE ID=?");
$WF_AbName->bind_param('i',$AbilityMods);
$WF_AbName->execute();
$WF_AbName->bind_result($Mod_Name);
$WF_AbName->fetch();
$Ability_Name[] = $Mod_Name;
}
print_r($Ability_Name);
See below:
SELECT ModID,
ID,
Name
FROM modifications M
LEFT JOIN wfabilities WF
ON WF.ModID = M.ID
WHERE TYPE =1 & WFAbility = '0'
To do this, you need to join your tables, I'm not quite sure what you are trying to do so you might have to give me more info, but here is my guess.
SELECT ID, Name, ModID
FROM modifications
JOIN wfabilities
ON WFID = ID
WHERE TYPE = '1'
AND WFAbility = '0'
In this version I am connecting the tables when WFID is equal if ID. You will have to tell me exactly what is supposed to be hooking to what in your requirements.
To learn more about joins and what they do, check this page out: MySQL Join
Edit:
After looking at your larger structure, I can see that you can do this:
SELECT modifications.Name FROM modifications
JOIN wfabilities on wfabilities.ModID = modifications.ID
JOIN warframes on warframes.ID = wfabilities.WFID
WHERE warframes.Name = 'the name you want'
This query will get you an array of the ability_names from the warframes name.
This is the query:
"SELECT A.ID, A.Name,B.ModID,C.Name
FROM modifications as A
LEFT JOIN wfabilities as B ON A.ID = B.WFID
LEFT JOIN warframes as C ON C.ID = B.WFID
WHERE A.TYPE =1 AND A.WFAbility = '0' AND C.Name = ?"

Which JOIN to use

I'm trying to get info from a table.
I have boards and sub-boards. The column sub_id in table board tells me whether or not the board is a sub-board or not. If it is a sub-board then the id of the parent board is the value, if it isn't then the cell is null.
I wrote this to display whether or not a board has any sub-boards:
<?php
$data = mysql_query("SELECT * FROM board WHERE sub_id='$boardId'")
or die(mysql_error());
while($info = mysql_fetch_array( $data ))
{
Print "<br>Sub-collections:<br>";
Print "<font size='5pt'><a href='/board/index/".$info['id']."'>".$info['board_name']." </a></font>";
}
?>
This works fine.
Now I want to write a similar code to name the parent board (if the board is a sub) but this is where I'm having trouble.
I came up with:
<?php
$data = mysql_query("select * from board WHERE id='$boardId' AND sub_id IS NOT NULL") or die(mysql_error());
$issub = mysql_fetch_array($data);
?>
then using...
<?php if(($issub)): ?>
<?php echo $issub['sub_id'] ?>
<?php else: ?>
<?php endif ?>
To display.
The problem is without a join I cannot show anything other than the id of the parent board. I don't know which columns to join in order to extract info like board_name etc.
EDIT:
popovitsj's suggestion:
<?php
$data = mysql_query("SELECT * FROM board b WHERE EXISTS(SELECT * FROM board WHERE b.id = sub_id)") or die(mysql_error());
while($info = mysql_fetch_array( $data ))
{
Print "<br>Sub-collection of:<br>";
Print "<font size='5pt'><a href='/board/index/".$info['id']."'>".$info['board_name']." </a></font>";
}
?>
This works to a certain extent. It correctly displays the parent board on the subboard page, but also displays it erroneously on the parent board page.
EDIT2:
After researching LEFT JOIN at Meier's suggestion I eventually got it to work using this code:
SELECT * FROM board a LEFT JOIN board b ON a.sub_id = b.id WHERE a.sub_id LIKE b.id AND a.id='$boardId'
Before I answer the question: are you 100% sure that the $boardid does not come directly from http and is therefore manipulable by the user, so your users can not start a sql injection?
The join you need is a "outer self join". Outer join because you also want to display boards that do not have a parent. Outer join is also named left join.
A self join because the table is joined to itself. The trick with the self join is to give the table different names in the statement, so you can distinguish between th parent and the child.
A quick google search for "sql outer self join" gave me this, which explains it quite nicely.
The example is with employees and managers, and the managers are also employees. So the example is quite similar to yours:
http://blog.sqlauthority.com/2010/07/08/sql-server-the-self-join-inner-join-and-outer-join/
There are different solutions to this. One possible one is:
SELECT * FROM Board b
WHERE EXISTS
(SELECT * FROM Board
WHERE b.id = sub_id);
Another possible solution could be this, this only shows 'root' parent boards. (boards with no parents themselves).
SELECT * FROM Board b
WHERE sub_id IS NULL;

Categories