Jump to content

Suppress duplicated results


tHud
Go to solution Solved by kicken,

Recommended Posts

Hello,

I have 3 tables for clients, orders and the products they ordered.

 

Here are the tables...

Clients
CLIENT_ID
CLIENT_NAME

Orders
o_id

client_id
o_number
o_date

o_notes

 

Products
o_id
qty
name

 

I am getting the results I need with this query...

SELECT
    clients.CLIENT_ID, clients.CLIENT_NAME,
    orders.o_id, orders.client_id, orders.o_date, orders.o_number, orders.o_notes,
    products.o_id, products.qty, products.name
    FROM clients, orders, products
    WHERE clients.CLIENT_ID = orders.client_id
    AND orders.o_id = products.o_id
    AND orders.o_id = $theOrder

..and this is the php I use to display it...

while ($row = $result->fetch_assoc()) {

    echo "<h2>$row[CLIENT_NAME]</h2>";
    echo '<label>Date</label><input type="text" value="'.timechange($row['o_date']).'" readonly><br>';
    echo '<label>Order No.</label><input type="text" value="'.$row['o_number'].'" readonly><br>';
    echo '<label>Notes</label><input type="text" value="'.$row['o_notes'].'" readonly>';
    echo '<label>Product Qty.</label><input type="text" value="'.$row['qty'].'" readonly><br>';
    echo '<label>Product Name</label><input type="text" value="'.$row['name'].'" readonly><br>';
}

However - rather predictably I am getting three forms printed out as the results from MySQL look like this...post-84111-0-46330300-1404489238_thumb.jpg

 

Is it possible to somehow get my form to display the results, like this... post-84111-0-34665200-1404489250_thumb.jpg

 

I hope I'm explaining myself well enough - and thank you for reading. :)

Edited by tHud
Link to comment
Share on other sites

see my reply at the following link on how to do something once when a value changes - http://forums.phpfreaks.com/topic/289403-issue-showing-results-1-row-keeps-alternating/?do=findComment&comment=1483684

 

also, about your tables. the table you show for Products (i would name it order_details) should have an id (auto-increment), o_id (order id), product id, and quantity. the product name should be gotten by joining with your product/item table (whatever you have named it) via the product id.

 

i would also recommend using alias names for the tables in your query. your current query would become -

SELECT
    c.CLIENT_ID, c.CLIENT_NAME,
    o.o_id, o.client_id, o.o_date, o.o_number, o.o_notes,
    p.o_id, p.qty, p.name
    FROM clients c, orders o, products p
    WHERE c.CLIENT_ID = o.client_id
    AND o.o_id = p.o_id
    AND o.o_id = $theOrder
Link to comment
Share on other sites

Hi Mac - thanks for the advice which I am taking on board.

I am redesigning the table structure - hopefully, this is what you meant?

 

post-84111-0-46582500-1404567475_thumb.jpg

 

I'm afraid I am not well enough versed in php to understand the terminology in your other post (about data sections).

 

In this line...

// there is a previous data section, close it here...

 

I see that the data has been 'ouput'(?) previously - but I'm not sure what is meant by closing the data section.

Link to comment
Share on other sites

a data section would be whatever context you are building/outputting a block of related data as - html (close a </div> for example), table (fill a short/incomplete row for example) , form, xml, array, json... 'closing' it would be whatever syntax you need to add to end the previous section to finish it and make it valid. you may in fact not need to do anything, the pseudo code is general purpose.

Link to comment
Share on other sites

  • Solution

closing the data section just refers to generating the HTML to close the section on the page holding the information. For example closing out table or div tags.

 

An alternative way to process things is to build a multi-dimensional array out of the results. The way you do that is first decide on an array format and then choose unique values you can use to index various levels of the array.

 

In this case your array would end up having two levels. The first level would be the orders, and the second the products associated with each order, something like:

 

array(
  'o_id' => array(
    // order details
    , 'products' => array(
      //list of products
    )
  )
  , //additional orders
)
So to process that you need the unique values of o_id for the top level. As you loop the results you'd test if an entry for $row['o_id'] exists in the order list and if not create it, then add the product for the current row to the order indicated by $row['o_id']. Something like:

$orders = array();
while ($row=$query->fetch()){
   $oid = $row['o_id'];
   if (!isset($orders[$oid])){
      $orders[$oid] = array(
         'clientName' => $row['CLIENT_NAME']
	 , 'date' => $row['date']
	 , // rest of the fields
	 , 'products' => array() //empty array to hold products
      );
   }
   
   //Add the product to the order
   $orders[$oid]['products'][] = array(
      'name' => $row['productName']
      , 'qty' => $row['qty']
   );
}
Now $orders will contain a list of each order, and within each order you have the products array listing each product. You can use that to build your final HTML output:

<?php foreach ($orders as $o): ?>
<div class="order">
  <h1><?=htmlentities($o['clientName'])?></h1>
  <p>On: <?=htmlentities($o['date'])?></p>
  <p>Products ordered:</p>
  <ul>
  <?php foreach ($o['products'] as $p): ?>
     <li><?=htmlentities($p['name'])?>; qty: <?=htmlentities($p['qty']);?></li>
  <?php endforeach; ?>
  </ul>
</div>
<?php endforeach; ?>
  • Like 1
Link to comment
Share on other sites

Thank you Mac & Kicken :)

On this occasion I think that the array solution would be the best option for me.

 

Could I just ask (hopefully) one last question?

 

I have a fourth table now that tracks the number/ cost etc of items in the product table...

Array
(
    [3] => Array
        (
            [clientId] => 3
            [clientName] => Joe
            [o_date] => 2014-07-01
            [o_number] => 11112
            [o_notes] => blah blah
            [details] => Array
                (
                    [0] => Array
                        (
                            [qty] => 10
                            [cost] => 19.5
                        )

                    [1] => Array
                        (
                            [qty] => 2
                            [cost] => 250.5
                        )

                )

            [products] => Array
                (
                    [0] => Array
                        (
                            [prod_id] => 1
                            [product] => door
                        )

                    [1] => Array
                        (
                            [prod_id] => 2
                            [product] => window
                        )

                )

        )

)

I would like to output the sub-arrays details and products but I'm failing with the nested for-each loops.

The results are getting duplicated.

<table border="1">

<?php foreach ($orders as $o): ?>

	<?php foreach ($o['details'] as $d): ?>
	<?php foreach ($o['products'] as $p): ?>


		<tr>
		<td>  Qty: <?=htmlentities($d['qty'])?>; </td>
		<td>  id: <?=htmlentities($p['prod_id'])?>; </td>
		<td>  Name: <?=htmlentities( $p['product']);?></td>
		</tr>

		<?php endforeach; ?>
		<?php endforeach; ?>


<?php endforeach; ?>


</table>


I have beeen Googling on how to do this, but can't find a solution.

 

Thank you again.

 

 

Link to comment
Share on other sites

I would imagine that you could just GROUP BY o_id.

SELECT
    c.CLIENT_ID, c.CLIENT_NAME,
    o.o_id, o.client_id, o.o_date, o.o_number, o.o_notes,
    p.o_id, p.qty, p.name
    FROM clients c, orders o, products p
    WHERE c.CLIENT_ID = o.client_id
    AND o.o_id = p.o_id
    AND o.o_id = $theOrder
    GROUP BY o.o_id

And you definitely need to redesign your database schema and use JOINs,  otherwise, you are multiplying the number of rows from each table you have after FROM clients, orders, products
 

Link to comment
Share on other sites

to include the price, you would still only have two levels in the array and two foreach() loops, because the price information would be retrieved in the query.

 

price would just become another value in the second-level array, using the example array build logic from kicken's post -
 

//Add the product to the order
$orders[$oid]['products'][] = array(
'name' => $row['productName']
, 'qty' => $row['qty']

,'cost' => $row['cost']
);

 

  • Like 1
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.