MySQL what kind of query i need to use - php

i'm making a panel where i can manage my users, i want to show username, email, and i want to show how much orders the placed. In my database i have 2 tabels 1 users, 1 orders. I'm saving the username from the user in the order table so i know wich user has bought it.
But, i want to write a panel with a overview from my users in a foreach loop. I have the loop for username, email how i can add the amount of order to it.
<?php
$model = $connection->createCommand('SELECT * FROM user');
$adminAccounts = $model->queryAll();
foreach($adminAccounts as $results){
$accounts['id'] = $account_id;
$accounts['username'] = $results['username'];
$accounts['email'] = $results['email'];
$accounts['rest'] = $results;
echo "
<tr>
<td>
<p>" . $newValidation->safeEcho($accounts['username']) ." </p>
</td>
<td>
<p>" . $newValidation->safeEcho($accounts['email'])." </p>
</td>
</tr>
";
}
Lets say my table look likes this
<username> <email>
Now i want it to look like this
<username> <email> <total orders>
I was thinking i should use a inner join but how i can do that ?
Greetz

I think you can change your query to:
SELECT user.*, t.cnt FROM user JOIN (SELECT gebruikersnaam, COUNT(*) AS cnt FROM orders GROUP BY gebruikersnaam) t ON user.username = t.gebruikersnaam
With this query you can get users orders but you will skip users without orders, so to get them you can do LEFT JOIN:
SELECT user.*, t.cnt FROM user LEFT JOIN (SELECT gebruikersnaam, COUNT(*) AS cnt FROM orders GROUP BY gebruikersnaam) t ON user.username = t.gebruikersnaam
I suggested that the field for users in table orders is username. And in your question you point that the table is users but in your query table is user. I am using user. If you change your current query with this one you can add in your code:
foreach($adminAccounts as $results){
$accounts['id'] = $account_id;
$accounts['username'] = $results['username'];
$accounts['email'] = $results['email'];
$accounts['total_orders'] = ($results['cnt'] == NULL) ? 0 : $results['cnt']; // orders per user
$accounts['rest'] = $results;
echo "
<tr>
<td>
<p>" . $newValidation->safeEcho($accounts['username']) ." </p>
</td>
<td>
<p>" . $newValidation->safeEcho($accounts['email'])." </p>
</td>
<td>
<p>" . $newValidation->safeEcho($accounts['total_orders'])." </p>
</td>
</tr>
";
}

Related

Mysql join allowing ID to be used as a button link on inner join on null value of linked table

I am not sure how to phrase my question without some background information.
I have 2 tables: accounts and rosters
accounts
id - PK
stafffname
rosters
rosterID - PK
id - FK link to accounts table
monday
tuesday
etc..
I am trying to create an edit table in php.
This is my current output
$sql = "SELECT * FROM accounts LEFT OUTER JOIN rosters ON accounts.id=rosters.id
WHERE stafffname<>'admin' ORDER BY rosters.week_start ASC, accounts.stafffname ASC";
$result = $mysqli->query($sql);
if($result->num_rows > 0)
{
while($row = $result->fetch_assoc())
{
$comments = str_replace('+', '<br/>', $row['comments']);
$comments = str_replace('{', '<strong/>', $comments);
$comments = str_replace('}', '</strong/>', $comments);
echo '
<tr class><!-- 2nd row STAFF MEMBER 5-->
<td><!--Date Range-->
'.$row["stafffname"].'
'.$row["id"].'
</td>
<td><!--Date Range-->
'.date("d M Y", strtotime($row["week_start"])).'
</td>
<td><!--Mon Time-->
'.substr($row["mon_start"],0,5).' - '.substr($row["mon_end"],0,5).'
</td>
<td><!--Tue Time-->
'.substr($row["tue_start"],0,5).' - '.substr($row["tue_end"],0,5).'
</td>
<td><!--Wed Time-->
'.substr($row["wed_start"],0,5).' - '.substr($row["wed_end"],0,5).'
</td>
<td><!--Thu Time-->
'.substr($row["thu_start"],0,5).' - '.substr($row["thu_end"],0,5).'
</td>
<td><!--Fri Time-->
'.substr($row["fri_start"],0,5).' - '.substr($row["fri_end"],0,5).'
</td>
<td><!--Sat Time-->
'.substr($row["sat_start"],0,5).' - '.substr($row["sat_end"],0,5).'
</td>
<td><!--Comments-->
'.$comments.'
</td>
<td><!--Comments-->
Add
Edit
</td>
</tr>
';
}
The query works fine and it list the users with the Null values.
What I am trying to get working is: there is an add and edit button connected to the row but when there is a null value in the rosters table, the id from the accounts table is not passed to the add or edit button.
Is there a way for the id to be passed to the add and edit button?
Do I need a different type of query.
I have tried Cross Joins and other combinations, but it only lists the ID when there is data in both tables.
Thanks
You are currently using a LEFT OUTER JOIN with your accounts table on the left and your rosters table on the right. This means that SQL will return all records from accounts along with any matching records from rosters if they are found.
It sounds like you want to use a FULL OUTER JOIN which will return records from both tables, joining them when they match the condition in the where clause.

MAX and COUNT sql query

I need to know how to use MAX() and COUNT() query to display the "fiser" table entries that contain the primary "codp" key that comes from the "products" table, depending on a previously selected period?
Table products : codp, denp ;
Table orders: codc,codp ;
Table returns : codr, datar, codc, codp
<?php
if(isset($_POST['add'])){
$sql = "SELECT p.denp, a.datar,MAX(p.codp)
FROM ( SELECT COUNT(p.codp) FROM products p ) products p
INNER JOIN orders o ON p.codp=o.codp
INNER JOIN returns r ON o.codc=r.codc
WHERE r.datar>=STR_TO_DATE('".$_POST['d1']."','%Y-%m-%d')
AND r.datar<=STR_TO_DATE('".$_POST['d2']."','%Y-%m-%d') ";
$result = mysqli_query($conn, $sql);
$queryResult = mysqli_num_rows($result);
if($queryResult > 0 ){
while ($row = mysqli_fetch_assoc($result)) {
echo "
<table border=1 >
<tr>
<td><p> ".$row['codp']." </p></td>
<td><p> ".$row['denp']." </p></td>
<td><p> " .$row['codr']." </p></td>
<td><p> " .$row['datar']." </p></td>
<td><p> " .$row['codc']." </p></td>
</tr> </table> ";
}
} else {
echo " No results!" ;
}
}
?>
You should use group by for codp and the join the related result eg:
$sql = "SELECT p.denp, r.datar,MAX(p.cnt_codp)
FROM (
SELECT codp, COUNT(*) as cnt_codp FROM products
group by codp
) products p
INNER JOIN orders o ON p.codp=o.codp
INNER JOIN returns r ON o.codc=r.codc
WHERE r.datar>=STR_TO_DATE('".$_POST['d1']."','%Y-%m-%d')
AND r.datar<=STR_TO_DATE('".$_POST['d2']."','%Y-%m-%d')
GROUP BY p.denp, r.datar ";
and you should check for your db driver for param bindig instead of use of php var in sql (you are at risk for sql injection)
and you should also use a group by for not aggreated column or reeval the question if you need the values related to max result (the use of aggregation function without a proper group by columns for not aggreagated is depreacted in sql ai the most recent version of mysql is not allowed)

MySQL: Displaying only the info in one table that is not already in displayed from another table

My goal is to display all user's names and their availability for a specific match. The following code does that. Might not be the easiest way but I am new to this and it works for now.
//Display match dates and times(showing all matches)
$stmt = $conn->prepare('SELECT * FROM matches
WHERE tid=:tid /*AND datetime BETWEEN (NOW() + INTERVAL 24 HOUR) AND (NOW() + INTERVAL 28 DAY)*/
ORDER BY datetime');
$stmt->bindParam(':tid', $tid, PDO::PARAM_INT);
$stmt->execute();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
echo "
<h2>".date("F j",strtotime($row["datetime"])). " # ".date("g:i A",strtotime($row["datetime"]))."<br></h2>
<h3>"$row[location] Match <br> vs $row[opponent]</h3>";
echo "<table>
<tr>
<th>Player</th>
<th>Availability</th>
</tr>
</table>";
//Get available(Yes) users first and last names to display
$stmtY = $conn->prepare("SELECT user.first, user.last
FROM user
INNER JOIN match_part ON user.uid=match_part.uid
WHERE mid=:mid AND availability = 'Yes'");
$stmtY->bindParam(':mid', $row['mid'], PDO::PARAM_INT);
$stmtY->execute();
while ($rowY = $stmtY->fetch(PDO::FETCH_ASSOC))
{
echo "<table class='match-avail'>
<tr>
<td>$rowY[first] $rowY[last]</td>
<td><span style='color: #70db62'>✔</span></td>
</tr>
</table>";
}
//Get unavailable(No) users first and last names to display
$stmtN = $conn->prepare("SELECT user.first, user.last
FROM user
INNER JOIN match_part ON user.uid=match_part.uid
WHERE mid=:mid AND availability = 'No'");
$stmtN->bindParam(':mid', $row['mid'], PDO::PARAM_INT);
$stmtN->execute();
while ($rowN = $stmtN->fetch(PDO::FETCH_ASSOC))
{
echo "<table class='match-avail'>
<tr>
<td class='Avail_No'>$rowN[first] $rowN[last]</td>
<td><span style='color: #b20000'>✘</span></td>
</tr>
</table>";
}
The above gives me the exact information I want.
Where I am stuck is...
I have team_members table (tmid, uid, tid) with a list of all players on a given team
A match_part table (mpid, mid, uid, availability) with the availability of the players who have entered their availability for a specific match.
I now want to show the people who have not yet given their availability. Therefore, I need to show the team_members names who do not exist in the match_part table. So I need to display only the names of players that are in the team_members table and not in the match_part table.
So something along the lines of...
$stmtU = $conn->prepare("SELECT user.first, user.last
FROM user
INNER JOIN team_members ON user.uid=team_members.uid
INNER JOIN match_part ON user.uid=match_part.uid
WHERE ***team_member.uid is not in match_part.uid***");
$stmtU->bindParam(':tid', $tid, PDO::PARAM_INT);
$stmtN->bindParam(':mid', $row['mid'], PDO::PARAM_INT);
$stmtU->execute();
while($rowU = $stmtU->fetch(PDO::FETCH_ASSOC))
{
echo "<table class='match-avail'>
<tr>
<td>$rowU[first] $rowU[last]</td>
<td>?</td>
</tr>
</table>";
}
Sorry for the lengthy post but I figured the information might help understanding the goal here. Thank you to all who have any thoughts/solutions. Your help is greatly appreciated!
if i understand correct you need the team_members.uid that are not in match part
for this you could use a not in with subselect
$stmtU = $conn->prepare("SELECT user.first, user.last
FROM user
INNER JOIN team_members ON user.uid=team_members.uid
where team_members.uid not in ( select uid from match_part)");

Could i merge this two select query in one?

My aim is to show/display in the right part questions of the survey (from a table of my database) and in the left part answers from customers (from another table in my database) in the right part. So my question is : How to merge this two select query ? I did some research but with php it's kind of tricky to understand and I'm still new on php too.
Any help or advices are welcome .
Best Regards A.V.
<?php
include("bdconnect_Foredeck.php");
$link=mysqli_connect($host,$login,$pass,$dbname);
if(isset($_POST["bouton55"])){
$link = mysqli_connect($host,$login,$pass,$dbname);
$id = $_REQUEST["Zoubi"];
$ClientRef =$_REQUEST["KGB"];
$rechercheq = "SELECT Qref,Ref,Question FROM questionnaire WHERE Qref ='$id' ";
$recherche= "SELECT choix,commentaire FROM reponse WHERE RefQ ='$id' and ref_Client ='$ClientRef'";
mysqli_query($link,$recherche);
mysqli_query($link,$rechercheq);
$result1=mysqli_query($link,$rechercheq);
$result= mysqli_query($link,$recherche);
while($row = mysqli_fetch_assoc($result,$result1)){
$Ref =$row["Ref"];
$Question =$row["Question"];
$Choix =$row["choix"];
$Commentara =$row["commentaire"];
echo" <tr bgcolor=\"white\">
<td> $id </td>
<td> $Ref </td>
<td>$Question </td>
<td>$Choix </td>
<td>$Commentara </td>
</tr>";
}
}
?>
You could use a JOIN
SELECT a.Qref, a.Ref,a.Question , b.choix, b.commentaire
FROM questionnaire as a
LEFT JOIN reponse as b ON a.RefQ = b.RefQ
WHERE a.Qref ='$id'
AND b.ref_Client ='$ClientRef'
if you have duplicated rows .. then you can use distinct
SELECT DISTINCT a.Qref, a.Ref,a.Question , b.choix, b.commentaire
FROM questionnaire as a
LEFT JOIN reponse as b ON a.RefQ = b.RefQ
WHERE a.Qref ='$id'
AND b.ref_Client ='$ClientRef'
otherwise you logic don't permit a single query

DISTINCT - download the content again

this is how I should use distinct to download the content again.
Here at pictures VISR it to the download content 3 times, but I only want it 1 time in total
what is the problem is that it does not pick all of them, but I only want it to pick up only one of time, which means that it only need to download one time by title and simultaneously username.
$sql = "SELECT DISTINCT fms_bruger.fornavn, fms_bruger.efternavn, fms_opslagpm.id, fms_opslagpm.title FROM fms_bruger INNER JOIN fms_opslagpm ON fms_bruger.id=fms_opslagpm.fra_id WHERE fms_opslagpm.til_id = ? ORDER BY fms_opslagpm.datotid DESC";
if ($stmt = $this->mysqli->prepare($sql)) {
$stmt->bind_param('i', $id);
$id = $_SESSION["id"];
$stmt->execute();
$stmt->bind_result($fornavn, $efternavn, $id, $title);
while ($stmt->fetch()) {
?>
<tr class="postbox">
<td class="beskedinfo">
<p><?php echo $fornavn . " " . $efternavn;?></p>
</td>
<td>
<?php echo $title;?>
</td>
<td>
Slet
</td>
</tr>
<?php
}
$stmt->close();
}
You need to use GROUP BY not DISTINCT to get the grouping of the title field.
SELECT fms_bruger.fornavn, fms_bruger.efternavn, fms_opslagpm.id, fms_opslagpm.title
FROM fms_bruger
INNER JOIN fms_opslagpm ON fms_bruger.id=fms_opslagpm.fra_id
WHERE fms_opslagpm.til_id = ?
GROUP BY fms_opslagpm.title
ORDER BY fms_opslagpm.datotid DESC
SELECT DISTINCT does exactly what it says: it selects distinct rows.
You include id in the columns. I'm pretty sure IDs will be unique, therefore all rows are DISTINCT.
Consider removing the DISTINCT keyword and adding a GROUP BY `fms_bruger`.`title` clause. This is an extension to the SQL standard which will return an arbitrary row for each unique title.

Categories