tags:

views:

111

answers:

3

Let's say you've got a table like this:

ID  Cat1  Cat2
1    a     red
2    b     red
3    c     blue
4    d     blue
5    e     blue
6    f     green
etc  etc   etc

The goal is to display the ID and Cat1 (unique pairs), split into groups according to Cat2. The easy way out is to run a separate MySQL query for each Cat2, but with a lot of different Cat2 values that produces an order of magnitude more queries to display one page to the viewer than just grabbing the whole lot of data in one query and slicing it apart with PHP.

I've got my formatting finished. But I'm having a hard time figuring out how to limit my row output based on the third column value in the array $value[2] taken from $value = mysql_fetch_row($result) after using
$sql = "SELECT ID,Cat1,Cat2 FROM MyTable ORDER BY Cat2,ID"

In plain English (clearly NOT real code) it would look like:

$result = mysql_query($sql);

IF ($value[2] from $value = mysql_fetch_row($result) = "red")
    {
        echo "Red Group";
        WHILE ()
 {
  echo $value[0] and $value[1] for all the rows where Cat2 = red
 }
    }

IF ($value[2] from $value = mysql_fetch_row($result) = "blue")
    {
        echo "Blue Group";
        WHILE ()
  {
  echo $value[0] and $value[1] for all the rows where Cat2 = blue
  }
    }
etc

Does all that make sense? How do you grab those groups of data out of the $result array?

Apparently is does NOT all make sense! :-) Here’s an example of desired output:

RED GROUP
1  a
2  b

BLUE GROUP
3  c
4  d
5  e

GREEN GROUP
6  f

etc

Thank you!

A: 

What you want to do is just limit the rows that your database will return using SQL's WHERE statement. Much easier:

$sql = "SELECT ID,Cat1,Cat2 FROM MyTable ORDER BY Cat2,ID";
$result = mysql_query($sql, $link) or die('Error');

$last_group = '';

echo '<table>';

while (list($id, $cat1, $cat2) = mysql_fetch_row($result))
{
    if ($cat2 != $last_group)
    {
        echo '<tr><td colspan="2">'.$cat2.' group</td></tr>';
    }

    echo '<tr><td>'.$id.'</td><td>'.$cat1.'</td></tr>';

    $last_group = $cat2;
}

echo '</table>';
Franz
I'm not anywhere I can test it at the moment, but your WHILE statement looks like the solution I was looking for. The $sql I already know, that's not an issue. Thank you, I'll report back when I can and award you the check if it does what I need. If not, I guess I'll have to provide more information.
Andrew Heath
So why did you not want to add the `WHERE` statement to your query? Or did you figure it out just now?
Franz
I didn't add a WHERE statement because the table has only those 3 columns, and I need to display every single row of the table. There's no need to use WHERE as I'm grabbing everything.By the way, not sure how to get from your suggestion to my desired output. Please see the example of desired output I just added.
Andrew Heath
This should work now.
Franz
I didn't completely understand your question at first, so it seems. However, you can now add CSS classes to the table rows for example to get different colored output for every row. This way you could even save yourself the "headline" rows and all the logic hassle involved with that.
Franz
Huh? Why the downvote?
Franz
Wasn't from me! Thanks for the effort, michaelk takes the prize today though.
Andrew Heath
+3  A: 

I don't know if I understand you correctly, but would this solve your problem?

The basic idea is that you loop through all rows and always save the last value of Cat2. Whenever you detect that Cat2 changes, you can insert the "header" for a new Cat2. Because you sort your results according to Cat2 first, this will create the output you want.

$query = "SELECT ID,Cat1,Cat2 FROM MyTable ORDER BY Cat2,ID"
$result = mysql_query($query);
$last = "";
while ($line = mysql_fetch_row($result)) {
  if ($line[2] != $last) {
    echo $line[2] . ' Group';
    $last = $line[2];
  }
  echo $line[0] . ' ' . $line[1];
}
michaelk
Please see the output example I just posted.
Andrew Heath
Have you tried my solution? It displays exactly the output you want...
michaelk
I've added a short explanation for my solution. Hope it helps ;)
michaelk
It makes sense sitting here reading it, but I won't be able to test it until I'm back in front of my work station as I wrote in another comment. I'll let you know. Thank you for your effort so far!
Andrew Heath
Flawless victory! <br />Thank you very much! Last question: was that a solution you just intuitively understood? Bred from a great deal of experience? Or was that a relatively simple question to begin with? I've only been doing PHP for ~4 weeks and it's my first programming language. Thank you for the help!
Andrew Heath
It's pretty simple once you figure out grouped output for the first time. Then of course you have to understand the question and it is really simple ;)
Franz
A: 

I'll say, would probably do it

$result = array();
foreach($data as $row){
 if(isset($result[$row['Cat2']])){
   $result[$row['Cat2']][] = $row;
 } else {
   $result[$row['Cat2']] = array( $row );
 }
}

it would give an array grouped by Cat2 after it's just double looping to that array to get the output desired.

RageZ