I'm trying to output a dynamic table using PHP that looks something like this:
Paul 56
Paul 6
Paul 78
Paul 34
Paul 76
Mark 56
Mark 5
Mark 34
Mark 87
Mark 23
Mark 765
Basically what I want to output is something like this:
<table>
<tr colspan="2">Name: Paul</tr>
<tr><td>56</td><td>Edit</td></tr>
<tr><td>6</td><td>Edit</td></tr>
<tr><td>78</td><td>Edit</td></tr>
<tr><td>34</td><td>Edit</td></tr>
<tr><td>76><td>Edit</td></tr>
<tr colspan="2">Name: Mark</tr>
<tr><td>56</td><td>Edit</td></tr>
<tr><td>5</td><td>Edit</td></tr>
<tr><td>34</td><td>Edit</td></tr>
<tr><td>87</td><td>Edit</td></tr>
<tr><td>23/td><td>Edit</td></tr>
<tr><td>765/td><td>Edit</td></tr>
</table>
What my PHP code looks like so far:
<?php
$name_holder = null;
for($i=0;$i<count($data);$i++) {
if($name_holder != $data[$i]->name){
$name_holder = $data[$i]->name;
//not sure what to do here??
}
echo "<tr>";
echo "<td align='left'>".$data[$i]->name."</td>";
echo "<td align='left'>".$data[$i]->hour."</td>";
echo "</tr>";
}
?>
SQL
SELECT name,hour FROM checkin_tbl GROUP BY name ORDER BY name ASC;
You don't need to group your data at the database level. It is possible to do it that way, but for each group you'd need another SELECT to read the related data, and will result in excessive numbers of queries being sent to the database.
I've thus elected to read the data in using a straight query, which would be something like this:
SELECT name,hour FROM checkin_tbl ORDER BY name ASC;
I've not supplied the database code below, as it is not clear what database you are using (e.g. MySQL) or what interface you are using (e.g. PDO). I've thus emulated a data source using an array - I'm sure you can swap this out with a fetchAll() or a foreach() and a row fetch().
Thus, try something like this:
<?php
// Data from your database
$rawData = [
['Paul', 56],
['Paul', 6],
['Mark', 56],
['Mark', 5],
];
// Let's reformat this
$out = [];
foreach ($rawData as $pair)
{
$name = $pair[0];
if (!isset($out[$name]))
{
$out[$name] = [];
}
// Pop the value on the list
$out[$name][] = $pair[1];
}
// Use this to look at your structure
#print_r($out);
?>
<!-- Here's your rendering section -->
<?php foreach ($out as $name => $data): ?>
<tr colspan="2"><td>Name: <?php echo htmlentities($name) ?></td></tr>
<?php foreach ($data as $item): ?>
<tr><td><?php echo htmlentities($item) ?></td><td>Edit</td></tr>
<?php endforeach ?>
<?php endforeach ?>
My strategy is to format the data as much as possible outside of the template - your code and another answer here (at the time of writing) are mixing logic and layout excessively in my opinion, and you need to separate them out.
This is why I have switched to opening/closing PHP tags in the rendering section: this is broadly HTML with PHP snippets where dynamic output is required. You'll benefit from tag matching and syntax colouration in your IDE if you do it this way.
I've added htmlentities() in to protect against XSS.
Looking at the desired situation, there is absolutely no need for a GROUP BY.
In fact this is actually hindering your from displaying all records for a given person. You will end up with one row per person, filled with the last record for that person.
In order to get the situation you desire, strip the GROUP BY.
A PHP solution COULD be.
$name_holder = null;
for($i=0;$i<count($data);$i++) {
if($name_holder != $data[$i]->name){
$name_holder = $data[$i]->name;
echo "<tr><td colspan='2'>Name: " . $name_holder . "</td></tr>"
}
echo "<tr>";
echo "<td align='left'>".$data[$i]->hour."</td>";
echo "<td align='left'>edit</td>";
echo "</tr>";
}
You were well on the way to a correct solution.
Background info on Grouping and your problem:
A good explanation is found here: http://www.tutorialspoint.com/sql/sql-group-by.htm
A demo that it will not work can be tested on the w3schools demo database: http://www.w3schools.com/sql/trysql.asp?filename=trysql_select_groupby
All records:
SELECT CustomerId, ShipperId FROM [Orders] WHERE ShipperId = 1
Grouped:
SELECT CustomerId, ShipperId FROM [Orders] WHERE ShipperId = 1 GROUP BY ShipperId
Related
I'm currently learning php/mysql, and I have a project.
I have 3 main SQL tables:
animations contains names, dates, adresses, etc
animateurs ('workers') is a list of people with many data
crosstable is a many-to-many relationship between the two other tables. Each line contains an "animationId", an "animateurId" and a status (is he/she interested, free, or not?).
many-to-many SQL table
I'm trying to make a web table showing all the animations, with one columns containing the animators. I would like to sort them based on their status. This is what I managed to do so far:
my results table atm
(I'm still pretty proud, having started learning php and SQL 1 month ago and not being a programmer... but whatever).
At first, I tried to run multiple while loops with $rowDispos but it doesn't seem to reset.
I think I might run one loop and create different arrays for the status of each person for each animation but I'm not sure how to do this.
My objective is to have another list of people below "Disponibles :", labeled "If necessary :".
At some point, I'll need to gather data for all the people participating to one event (to send them an email for example).
Above all I'm not sure what would be the best way to achieve what I'm trying to do.
Thank you!
$sql = "SELECT * FROM animations LEFT JOIN crosstable ON animations.idAnimation = crosstable.idAnimation LEFT JOIN animateurs ON crosstable.idAnimateur = animateurs.idAnimateur";
$res = $pdo->query($sql);
if ($res->rowCount() > 0) {
echo "<table>";
echo "<tr>";
echo "<th>Nom de l'animation</th>";
echo "<th>Date</th>";
echo "<th>Horaire</th>";
echo "<th>Nombre d'animateurs</th>";
echo "<th>Animateurs disponibles</th>";
echo "<th>Ma disponibilité</th>";
echo "</tr>";
while ($row = $res->fetch()) {
echo "<tr>";
echo "<td>".$row['animationNom']."</td>";
//Date
$timeStamp=strtotime($row['dateAnim']);
$numJourAnim=date("w", $timeStamp);
$jourAnim=$jour[$numJourAnim];
echo "<td>" . $jourAnim . "</br>" . date("d/m/Y", strtotime($row['dateAnim'])) ."</td>";
//Heures
echo "<td>de ".substr($row['heureDebut'], 0, 5)."<br/>à " . substr($row['heureFin'], 0, 5)."</td>";
echo "<td>".$row['nombreAnim']."</td>";
echo "<td>";
$req = $pdo->prepare("SELECT * FROM animateurs JOIN crosstable ON animateurs.idAnimateur = crosstable.idAnimateur WHERE idAnimation = :idAnimation");
//echo $row['idAnimation'];
$req->bindParam(':idAnimation', $row['idAnimation']);
$req->execute();
echo "Disponibles :<br/>";
while ($rowDispos = $req->fetch()) {
if ($rowDispos['disponibilite']=="disponible") {
echo $rowDispos['prenom']. " " .$rowDispos['nom'] . "<br/>";
}
}
echo "<td>".'<input type="radio" id="disponibilite" name="disponibilite_id' . $row['idAnimation'] . '" value="disponible">Intéressé<br/>'.
'<input type="radio" id="disponibilite" name="disponibilite_id' . $row['idAnimation'] . '" value="non">Non disponible<br/>'.
'<input type="radio" id="disponibilite" name="disponibilite_id' . $row['idAnimation'] . '" value="siBesoin">Si nécessaire<br/>'.
"</td>";
echo "</tr>";
}
echo "</table>";
unset($res);
}
else {
echo "No matching records are found.";
}
idAnimateur prenom nom email gsm codePostal naissance statut francais anglais neerlandais tailleTShirt asmoTShirt idUser
37 Wanda Maximoff wanda#gmail.com 1111111 7000 1983-04-09 independant 1 0 0 L 0 2
36 Tony Stark tony#despunches.be 666 7000 2022-10-03 independant 1 1 1 L 0 1
To reexplain things:
I need a table with 1 line per animation (per event).
Each column contains data about that event (date, time, place,...).
One columns contains data about people for that event. They can be present, interested, or busy. I would like, in that column, to sort and list people between present, interested, and busy. This data is stored in crosstable, with the id's of the event, the people, and their "status" concerning that event (and probably other things later on).
I'll need (one step at a time, but it might be important) to send an email to all the people that are marked as "present" at an event.
For now, let's stick with the query inside the while () loop. You want the animateurs stored by their status. You currently have:
SELECT *
FROM animateurs
JOIN crosstable ON animateurs.idAnimateur = crosstable.idAnimateur
WHERE idAnimation = :idAnimation
Currently you're only using 3 columns. In that case it's better to really name those columns:
SELECT
animateurs.disponibilite,
animateurs.prenom,
animateurs.nom
FROM animateurs
JOIN crosstable ON animateurs.idAnimateur = crosstable.idAnimateur
WHERE crosstable.idAnimation = :idAnimation;
Note how I make clear, every time, in which table a column is located. It might not be needed now, but when queries become more complex it will prevent errors.
Now you could use three queries to get the three status groups:
SELECT
animateurs.disponibilite,
animateurs.prenom,
animateurs.nom
FROM animateurs
JOIN crosstable ON animateurs.idAnimateur = crosstable.idAnimateur
WHERE crosstable.idAnimation = :idAnimation AND
crosstable.disponibility = 'disponible';
And the same for the 'non' and 'sieBesoin' people. However, we like to do this in one query. I would keep it simple and use this:
SELECT
animateurs.disponibilite,
animateurs.prenom,
animateurs.nom,
crosstable.disponibility
FROM animateurs
JOIN crosstable ON animateurs.idAnimateur = crosstable.idAnimateur
WHERE crosstable.idAnimation = :idAnimation;
Now you can sort them in PHP:
$animateurGroups = [];
while ($rowDispos = $req->fetch()) {
$disponibility = $rowDispos['disponibilite'];
$animateurGroups[$disponibility][] = $rowDispos['prenom']. " " .$rowDispos['nom'];
}
And then you can display the three groups like so:
foreach ($animateurGroups as $disponibility => $animateurGroup) {
echo "Disponibles: $disponibility<br/>";
foreach ($animateurGroup as $animateur) {
echo "$animateur<br>";
}
}
Later you should try and get the query completely out of this while () loop.
OK, I will try to put only a single query outside of the while () loop. We'll follow the same strategy as before, but now we have to add in the information about the animations, keeping in mind that there can be animations without any animators.
I now notice that the main query you have already does this:
SELECT *
FROM animations
LEFT JOIN crosstable ON animations.idAnimation = crosstable.idAnimation
LEFT JOIN animateurs ON crosstable.idAnimateur = animateurs.idAnimateur";
However, I always like to specify what I take from database, if only so that I can tell what is there, because I haven't got your database.
SELECT
animations.idAnimation,
animations.animationNom,
animations.dateAnim,
animations.heureDebut,
animations.heureFin,
animateurs.disponibilite,
animateurs.prenom,
animateurs.nom,
crosstable.disponibility
FROM animations
LEFT JOIN crosstable ON animations.idAnimation = crosstable.idAnimation
LEFT JOIN animateurs ON crosstable.idAnimateur = animateurs.idAnimateur";
Now we need to sort these results in PHP:
$animations = [];
while ($rowDispos = $req->fetch()) {
$idAnimation = $rowDispos['idAnimation'];
if (!isset($animations[$idAnimation]) {
$animations[$idAnimation] = ['animationNom' => $rowDispos['animationNom'],
'dateAnim' => $rowDispos['dateAnim'],
'heureDebut' => $rowDispos['heureDebut'],
'heureFin' => $rowDispos['heureFin']];
}
$disponibility = $rowDispos['disponibilite'];
if (!is_null($disponibility)) {
$animateurNom = $rowDispos['prenom']. " " .$rowDispos['nom'];
$animations[$idAnimation]['animateurGroups'][$disponibility][] = $animateurNom;
}
}
Note that I have no way to check this code myself, so I cannot guarantee it is correct.
Now that we have gathered everything in an array we can render the HTML table. This is a very much simplified version of that:
foreach ($animations as $idAnimation => $animation) {
echo $animation['animationNom'] . '<br>';
echo $animation['dateAnim'] . '<br>';
echo $animation['heureDebut'] . '<br>';
echo $animation['heureFin'] . '<br>';
if (isset($animation['animateurGroups']) {
foreach ($animation['animateurGroups'] as $disponibility => $animateurGroup) {
echo "Disponibles: $disponibility<br/>";
foreach ($animateurGroup as $animateur) {
echo "$animateur<br>";
}
}
}
}
This basically outputs everything on lines, not in a table, you I think you can see how you can turn this back into a table.
Storing everything in an array will work well for a limited number of animations. If you have thousands of them you should use LIMIT in your query.
Again, I must stress that I cannot properly test this code, and I know mistakes are quickly made. However, I think this should get you started.
I am trying to create a php script that gets values from a MySQL database, displays a header with the time_stamp that comes from an array, and a sub header with a value called "working_ra" with values underneath those categories. The values that go underneath both categories are being displayed in a table. I am sorting the values of the working_ra in the query so I can run a while loop saying that if they're not the same to display the next working_ra and continue echoing values. Here is my code:
foreach ($date as $i) {
echo "<pre>"."<h2>".$i."</h2>"."</pre>";
$result = mysqli_query ($con, "SELECT * FROM Signing WHERE value1 = 'Ings' AND time_stamp = '$i' ORDER BY working_ra");
$num_results = mysqli_num_rows($result);
$row = mysqli_fetch_array($result);
$desk = $row["working_ra"];
echo "var_desk starting value ","<b>", $desk,"</b>";
echo "<table border='1'>";
echo "<tr>";
echo "<td>", $row["first"],"</td>";
echo "</tr>";
while ($row = mysqli_fetch_array($result)) {
if ((string)$desk != (string)$row["working_ra"]) {
echo "</table>";
$desk = $row["working_ra"];
echo "var_desk next value ","<b>",$desk,"</b>";
echo "<br />";
echo "<table border='1'>";
}
echo "<tr>";
echo "<td>", $row["first"],"</td>";
echo "</tr>";
}
$result->free();
}
$con->close();
Everything works fine until it hits to the second "desk" name. Then the tables that are supposed to be with the next value get shifted to the next date. Here is what it looks like on the page:
aSFashagh, Jeremy, Jeremy, and Johnny are all supposed to be under (Phil, January 10 2013) but is shifted down into the next date and working_ra (Phil, January 20 2013). zffaA, andsdfdsggsdhj are all supposed to be under (Phil,January 20 2013) but are under (Phil, February 25 2013) instead. Whats weird is that the method did work WITHOUT trying to put all of the values in tables.
My assumption is that it could be the ordering of which the table tags are ending and starting, but I have tried numerous amounts of things and still cannot figure out what is wrong.
EDIT
Sorry its very confusing to say. But im trying to get it to where everything is shifted up the way its supposed to be. Where the values of "first" belong with their corresponding time_stamp and working_ra. For instance, the value of Johnny in the MySQL db has a value of working_ra - Phil and a value of time_stamp - January 10, 2013. However as you can see, Johnny is not underneath (Phil, January 10 2013) instead January 20, 2013. Its not the query thats the problem, it has something to do with the while loop and the table and I just can't figure it out.
The only two values that are correct are Zack and Why which have corresponding values of (working_ra = "Bob", time_stamp = "January 10, 2013")
I believe your problem is with the mysql row pointer. You already used mysqli_fetch_array once before the while loop therefore shifting the current mysql row to the next row.
This code
mysqli_data_seek($result, 0);
will reset the pointer.
Place it right before your while loop.
Figured out what the problem was. I needed to add a "/table" tag when the while loop breaks.
Firstly let me apologise for my vague question title, this is my first post on this site; after spending 2 days searching for the answer to my question (and getting quite close in some cases) I've hit a wall. Normally I can find everything I need from stackoverflow but this time I've run out of ways to word my question in the search bar.
I have a mysql table containing data for clothes (tbl_clothing) and in this table (I've simplified this for my problem) I have columns: style, colour_url, size, carton_price
The 'style' is for a particulate type of garment $row['style'] in the first sql statement comes from the initial request to the database to find out if the users choice is actually a valid choice (don't worry I've sanitized it, no direct user input is ever used!)
I am grouping by colour_url to create an array of all the colour variations for the chosen style. Incidentally the colour_url is also the actual url to the image file for that colour (used later). Yes this does mean that in the database there is repeating data, the colour_url is repeated as many times as there are sizes for that colour - I've inherited it and can't change that yet.
I then iterate over this array 'foreach' of the different colours and perform another DB lookup to select all sizes and prices for the chosen style and the current colour.
Still in the above foreach loop I perform a while loop to create a second array to hold the sizes and prices (multiple rows are returned from the DB).
Still in the above foreach loop I perform another foreach loop on the second array to create the table structure for outputting.
This is now screaming at me that it is not the best way of achieving what I'm tying to do.
Am I just over thinking this or is there a much simpler way of doing things? I've tried doing a single sql lookup to retrieve a multidimensional array all in one hit but then cant separate out the data into correct groups I've been over and over transposing arrays re-looping through the array creating other "reference" arrays all without any success.
The basic logic works like this:
1 style = many colours
1 colour = many sizes
1 size = 1 price
And i'm trying to get a table output (for each colour) like this:
_________________________________
| (IMG A) | Size(1) | Size(2) | Size(3) |
| colour_A | Price(1) | Price(2) | Price(3) |
|_________|_______________________|
_________________________________
| (IMG B) | Size(1) | Size(2) | Size(3) |
| colour_B | Price(1) | Price(2) | Price(3) |
|_________|_______________________|
Here is my code, it does the job but this cant be the best way to do it:
$sql = "SELECT colour_url FROM tbl_clothing WHERE style = '".$row['style']."' GROUP BY colour_url";
$result = $mysqli->query($sql);
$numRows = $result->num_rows;
if ($numRows != 0){
while ($rowS = $result->fetch_assoc()){
$aResults[] = $rowS['colour_url'];
}
$result->free();
foreach ($aResults as $k=>$v){
echo "<table><tr><td rowspan='2'><img title='' alt='' src='".$v."' /></td>";
$sql = "SELECT size, carton_price FROM tbl_clothing WHERE style = '".$row['style']."' AND colour_url = '".$v."'";
$result = $mysqli->query($sql);
$numRows = $result->num_rows;
if ($numRows != 0){
$aSizePrice = array();
while ($rowS = $result->fetch_assoc()){
$aSizePrice[$rowS['size']] = $rowS['carton_price'];
}
$sizes = "";
$prices = "";
foreach ($aSizePrice as $key=>$val){
$sizes .= "<td>".$key."</td>";
$prices .= "<td>".$val."</td>";
}
}
$result->free();
echo $sizes;
echo "<tr>".$prices."</tr>";
echo "</tr></table>";
}
}
?>
Any help would be a hugely appreciated, even just a point in the right direction, a different opinion or even a sarcastic comment will do at this point...
One thing i might recommend right off the bat, seperate your concerns. You are trying to get data right from the database into your view layer. Instead, get your data, compile it into memory, THEN, display it. It will make your problem easier to solve right off the start.
For example:
//Prepare the data receptacle
$data = array();
//Query to data to work with
$result = $mysqli->query("SELECT * FROM tbl_clothing WHERE style = '".$row['style']."'");
$numRows = $result->num_rows;
while ($rowS = $result->fetch_assoc()){
//Make sure our data can be stored correctly into our structure
if(!isset($data[$row['style']])){ $data[$row['style']] = array(); }
if(!isset($data[$row['style']][$rowS['colour_url'])){ $data[$row['style']][$rowS['colour_url'] = array(); }
if(!isset($data[$row['style']][$rowS['colour_url']['sizes'])){ $data[$row['style']][$rowS['colour_url']['sizes'] = array(); }
if(!isset($data[$row['style']][$rowS['colour_url']['prices'])){ $data[$row['style']][$rowS['colour_url']['prices'] = array(); }
//Store the price and size
$data[$row['style']][$rowS['colour_url']['sizes'][] = $rowS['size'];
$data[$row['style']][$rowS['colour_url']['prices'][] = $rowS['carton_price'];
}
//At this point we have our data, let's just show it
?>
<table>
<?php foreach($data as $style => $color_urls){ ?>
<?php foreach($color_urls as $color_url => $content){ ?>
<tr>
<td rowspan="2">
<img title="" alt="" src="<?php echo $colour_url; ?>" />
</td>
</tr>
<tr>
<?php foreach($content['sizes'] as $size){ ?>
<td><?php echo $size; ?></td>
<?php } ?>
</tr>
<tr>
<?php foreach($content['prices'] as $price){ ?>
<td><?php echo $prices; ?></td>
<?php } ?>
</tr>
<?php } ?>
<?php } ?>
</table>
This is just a quick draft, i might not have understood your question correctly, you'll have to fix the errors and the miscomprehensions yourself. At least you have a good start with this!
Well, let's start with your query. In your first query, you claim you're trying to get all of the colors for a given style. You can use the DISTINCT keyword for that
SELECT DISTINCT colour_url
FROM tbl_clothing
WHERE style = ?
But that's not what you're actually looking to get - you actually want all of the color/size combinations in your database for a given style, which you would likely want to select thusly:
SELECT colour_url, size, carton_price
FROM tbl_clothing
WHERE style = ?
Once you've done that, you want to parse it into a data structure. (you should be parameterizing your queries - I recommend the PDO library, so I'll show you how that would work).
<?php
$db = new PDO('connection', 'user', 'pass');
$query = $db->prepare('SELECT colour_url, size, carton_price
FROM tbl_clothing
WHERE style = :style');
$query->bindValue(':style', $row['style'], PDO::PARAM_STR);
$query->execute();
$results = $query->fetchAll(PDO::FETCH_ASSOC);
$clothes = array();
foreach($results as $result){
if(!isset($clothes[$result['colour_url']]))
$clothes[$result['colour_url']] = array();
$clothes[$result['colour_url']][$result['size']] = $result['carton_price'];
}
?>
Your results are now in a series of nested maps - from $clothes[$color], you get a map from size to price. $clothes[$color][$size] will net you the price of a specific color and size, and you can choose to print them that way:
<?php
foreach($clothes as $color => $prices) {
$sizeStr = '<td>' . implode('</td><td>', array_keys($prices)) . '</td>';
$priceStr = '<td>' . implode('</td><td>', $prices) . '</td>';
?><table>
<tr>
<td rowspan="2">
<img title="" alt="" src="<?=$color?>" />
</td>
<?= $sizeStr ?>
</tr>
<tr>
<?= $priceStr ?>
</tr>
</table><?php
}
?>
Your code now reads a lot closer to english, which will make it easier to debug, and easier to pas on to others.
My connection to my database was successful. I now have all of the data from a table stored as an array in a php variable named $data. I am trying to extract three rows from this variable and display them with html.
Here is what my code looks like (with the exception of the connection info being removed):
<?php
$data = mysql_query("SELECT * FROM specs")
or die(mysql_error());
while ($row = mysql_fetch_assoc($data)) {
$rows[] = $row;
?>
I know that I can pull individual data from this variable and insert it into html successfully by entering code like this (for example):
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td>Model: <?php echo $row['name'];?></td>
</tr>
</table>
But my problem is that I want to display three separate rows of data from the database as three individual columns in a html table. (Hope that makes sense)
I've looked into how to do this with foreach and while but am not quite sure where I'm going wrong.
I'm hoping someone might be able to shed some light on this as I have read about foreach loops, while, and am still stuck! I'm also hearing that mysql_query is deprecated but ruled out not using this since our webserver is still using an old version of php and mysql and is not planning to update anytime soon.
Sorry if I'm not all here in my post - it's late and I'm tired. Thanks for your help in advance! I'll keep an eye on this in case anyone has questions.
This will print the array in a table with each row being 3 elements of the array.
echo "<table>";
for ($i = 0; $i < count($rows); $i += 3) {
echo "<tr>";
for ($j = 0; $j < 3; $j++) {
if (isset($rows[$i+$j]) {
echo "<td>Model: {$rows[$i+$j]['name']}</td>";
}
}
echo "</tr>";
}
echo "</table>";
It's simpler to limit the SQL to three rows, and then echo all incoming rows directly, without first adding to an array. That would waste resources.
<?php
echo "<table>";
$data = mysql_query("SELECT * FROM specs LIMIT 3")
or die(mysql_error());
while ($row = mysql_fetch_assoc($data))
echo '<tr></td>', $row['name'], '</td></tr>';
echo "</table>";
?>
Ah, but now I see it's a year old question. I hope you learned a lot in the meantime.
I'm working with symfony 1.4 and Doctrine. I'm writing an app about some pubs/bars, and I've got 4 tables:
products
orders
product_order
pubs.
I want to get the times all products have been ordered in the first pub (i.e. pubs.id = 1). This is what I've got, but I can only get the sum of the first product (products.id = 1) and I need the sum of all of them, in this case there are two different products in my db.
ProductOrderTable:
public function ordersGetCount(){
$q = Doctrine_Query::create()
->from('ProductOrder l')
->innerJoin('l.Order p ON l.id_order = p.id')
->select('SUM(l.amount) as units')
->andWhere('p.id_pub = 1')
->groupBy('l.id_product')
->orderBy('p.id');
return $q->execute();
}
Here my action class:
$this->resultCount= Doctrine_Core::getTable('productorder')->ordersGetCount();
And here my template:
for($i=0; $i<2; $i++){
echo "<tr>";
echo "<td>".$resultCount[0]->getUnits()[$i]."</td>";//
echo "<td>1</td>";
echo "<td>1</td>";
echo "</tr>";
}
Please need help :)
I think there's nothing wrong with your query, but you should have a look at how you display your results.
echo "<td>".$resultCount[0]->getUnits()[$i]."</td>";
Firstly, you're always referring to the first element in the $resultCount array. Secondly, I'm not sure if you can use a getter for a virtual column (you're not using a column which is mapped to your model.
So I would go with something like this:
In the ordersGetCount I would use
return $q->fetchArray();
This will return an array of arrays, not an array of objects, and will allow you to access the virtual column units.
To display the results:
<?php foreach ($resultCount as $row): ?>
<tr>
<td>
<?php echo $row['units']; ?>
</td>
<td>1</td>
<td>1</td>
</tr>
<?php endforeach ?>
EDIT:
This is quite strange ;) Can you try to build the query this way: (in theory it should be the same):
$q = $this->createQuery('l')
->select('l.id_product, sum(l.amount) as units')
->innerJoin('l.Order')
->where('p.id_pub = 1')
->groupBy('l.id_product')
->orderBy('p.id');
You must try remove
->groupBy('l.id_product')
it reduces you results to one product.