0

I'm trying to find a way to display my entity relations in a better way. My DB consists of 3 tables: members, fees and fees_has_members.

One member can have multiple fees and vice versa. The problem is when I want to display all members and their corresponding fees, my while loop runs through all entities and displays all information every time it loops.

The loop displays it like this:

Member A
Fee B
200 $

Member A
Fee C
230 $

Member A
Fee B
200 $

I want to display the Member once and all the related fees.

The code:

 <?php 
mysql_connect("#######", "########", "######") or die(mysql_error());
mysql_select_db("#####") or die(mysql_error());
?>

<h3>Members:</h3>
<?php
 $result = mysql_query("SELECT boder_boder_id, medlemmer_medlemmer_id, medlemmer_navn, medlemmer_id, boder_navn, boder_id, boder_pris FROM boder_has_medlemmer, medlemmer, boder WHERE boder_boder_id = boder_id AND medlemmer_medlemmer_id = medlemmer_id");
 ?>

 <?php
 if (mysql_num_rows($result) == 0)
 echo "Query returned 0 rows";
 ?>

 <?php
 $samlet = 0;
 while($row = mysql_fetch_array($result))
 { ?>

 <p>
 <?php
  echo $row[medlemmer_navn].'<br>'; 
  echo $row[boder_navn].'<br>';
  echo $row[boder_pris].' kr.';
  $samlet += $row[boder_pris];
 ?>
 </p>

I know i could change the MySQL query to include the specific member name, but then I would have to run 30 queries to display all members and their fees.

I hope I made myself clear.

Any suggestions?

2 Answers 2

1

Your idea with a query per member is silly :D

Try this.

<?php
mysql_connect('#######', '########', '#######') or die(mysql_error());
mysql_select_db('#####') or die(mysql_error());

echo '<h3>Members:</h3>';

$result = mysql_query('SELECT `boder_boder_id`, `medlemmer_medlemmer_id`, `medlemmer_navn`, `medlemmer_id`, `boder_navn`, `boder_id`, `boder_pris` FROM `boder_has_medlemmer`, `medlemmer`, `boder` WHERE `boder_boder_id` = `boder_id` AND `medlemmer_medlemmer_id` = `medlemmer_id`;');

if (!mysql_num_rows($result))
{
    echo 'Query returned 0 rows';
}

$samlet = 0;
$medlemmers = array();
while($row = mysql_fetch_array($result))
{
    $medlemmers[$row['medlemmer_navn']][] = $row;
}

foreach($medlemmers as $navn => $medlemmer)
{
    echo '<p>';
    echo $navn . '<br />';
    foreach($medlemmer as $row)
    {
        echo $row['boder_navn'] . '<br />';
        echo $row['boder_pris'] . ' kr.';
        $samlet += $row['boder_pris'];
    }
    echo '</p>';
}

It's not tested but should go in right direction ^^

Sign up to request clarification or add additional context in comments.

1 Comment

Yeah I know the idea is silly, as I pointed out :) I will test your suggestion right away.
1

A slightly different alternative using an object. This would save memory compared to reading all the data into an array.

Each time the name changes the object is unset (triggering the __DESTRUCT function to output the details) and a new object created

 <?php 
mysql_connect("#######", "########", "######") or die(mysql_error());
mysql_select_db("#####") or die(mysql_error());

echo "<h3>Members:</h3>";

$result = mysql_query("SELECT boder_boder_id, medlemmer_medlemmer_id, medlemmer_navn, medlemmer_id, boder_navn, boder_id, boder_pris 
                        FROM boder_has_medlemmer,
                            medlemmer,
                            boder 
                        WHERE boder_boder_id = boder_id 
                        AND medlemmer_medlemmer_id = medlemmer_id");

if (mysql_num_rows($result) == 0)
{
    echo "Query returned 0 rows";
}
else
{
    $prev_medlemmer_navn = '';
    while($row = mysql_fetch_array($result))
    {
        if ($prev_medlemmer_navn != $row['medlemmer_navn'])
        {
            unset($member_output);
            $member_output = new member_output($row['medlemmer_navn']);
            $prev_medlemmer_navn = $row['medlemmer_navn'];
        }
        $member_output->add_row($row['boder_navn'], $row['boder_pris'])
    }
    unset($member_output);
}

class member_output
{
    private $medlemmer_navn = '';
    private $details = array();
    private $samlet = 0;

    public function __CONSTRUCT($medlemmer_navn)
    {
        $this->medlemmer_navn = $medlemmer_navn;
    }

    public function __DESTRUCT()
    {
        echo "<p>";
        echo $this->medlemmer_navn.'<br />'; 
        foreach ($this->details as $detail)
        {
            echo $detail['boder_navn'].'<br />';
            echo $detail['boder_pris'].' kr.<br />';
        }
        echo $this->samlet.'<br />';
        echo "</p>";
    }

    public function add_row($boder_navn, $boder_pris)
    {
        $this->details[] = array('boder_navn'=>$boder_navn, 'boder_pris'=>$boder_pris);
        $this->samlet += $boder_pris;
    }
}

 ?>

Or you could push much of the work onto MySQL, grouping the details together so one row per name, then exploding out the rest of the fields.

 <?php 
mysql_connect("#######", "########", "######") or die(mysql_error());
mysql_select_db("#####") or die(mysql_error());

echo "<h3>Members:</h3>";

$result = mysql_query("SELECT medlemmer_navn, medlemmer_id, GROUP_CONCAT(CONCAT_WS('~~', boder_navn, boder_pris) SEPARATOR '##') AS details, SUM(boder_pris) AS samlet
                        FROM boder_has_medlemmer,
                            medlemmer,
                            boder 
                        WHERE boder_boder_id = boder_id 
                        AND medlemmer_medlemmer_id = medlemmer_id
                        GROUP BY medlemmer_navn, medlemmer_id");

if (mysql_num_rows($result) == 0)
{
    echo "Query returned 0 rows";
}
else
{
    while($row = mysql_fetch_array($result))
    {
        echo "<p>";
        echo $row['medlemmer_navn'].'<br />'; 
        $details = explode('##', $row['details']);
        foreach ($details as $detail)
        {
            list($boder_navn, $boder_pris) = explode('~~', $detail);
            echo $boder_navn.'<br />';
            echo $boder_pris.' kr.<br />';
        }
        echo $row['samlet'].'<br />';
        echo "</p>";        
    }
}

 ?>

Or a little dirty, building up the html within the sql.

 <?php 
mysql_connect("#######", "########", "######") or die(mysql_error());
mysql_select_db("#####") or die(mysql_error());

echo "<h3>Members:</h3>";

$result = mysql_query("SELECT medlemmer_navn, medlemmer_id, GROUP_CONCAT(CONCAT(boder_navn, '<br />', boder_pris, 'kr.', '<br />') ) AS details, SUM(boder_pris) AS samlet
                        FROM boder_has_medlemmer,
                            medlemmer,
                            boder 
                        WHERE boder_boder_id = boder_id 
                        AND medlemmer_medlemmer_id = medlemmer_id
                        GROUP BY medlemmer_navn, medlemmer_id");

if (mysql_num_rows($result) == 0)
{
    echo "Query returned 0 rows";
}
else
{
    while($row = mysql_fetch_array($result))
    {
        echo "<p>";
        echo $row['medlemmer_navn'].'<br />'; 
        echo $row['details']; 
        echo $row['samlet'].'<br />';
        echo "</p>";        
    }
}

 ?>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.