0

I am currently stuck attempting to understand how I loop results inside an existing loop using SQL results from joined tables.

Firstly, here is my current code:

<?php
include('OrderCore/connect-db.php');
$POIds = array();
if ($result = $mysqli->query("SELECT ProductionOrderID FROM ProductionOrder" ) ) {
    while ($row = $result->fetch_object()) {
        $POIds[] = $row->ProductionOrderID;
    }
}
foreach ( $POIds as $index => $OrderId ) {
    if ( $result = $mysqli->query("
    SELECT * 
    FROM ProductionOrder AS p
    LEFT JOIN ProductionOrderStatus AS s ON ( p.ProductionOrderID = s.ProductionOrderStatusID ) 
    LEFT JOIN NotGood AS n ON ( p.ProductionOrderID = n.NGID ) 
    LEFT JOIN BatchOrder AS b ON ( p.ProductionOrderID = b.ProductionOrderID)
    LEFT JOIN Brand AS bd ON ( p.ProductionOrderID = bd.BrandID ) 
    LEFT JOIN CustomerOrder AS co ON ( p.ProductionOrderID = co.COID ) 
    LEFT JOIN Customer AS c ON ( p.ProductionOrderID = c.CustomerID ) 
    LEFT JOIN CustomerOrderStatus AS cos ON ( p.ProductionOrderID = cos.COStatusID )
    WHERE p.ProductionOrderID='$OrderId'") ) {
        while( $row = $result->fetch_object() ) {
            print "<h1>Order: $OrderId</h1>";
            print "<table class='table table-striped'>";
            print "<tr> <th>PO ID</th> <th>PO #</th> <th>Order Quantity</th> <th>Balance Left</th> <th>Production Date</th> <th>Production Order Status</th> <th>Not Good ID</th> </tr>";
            print "<td>" . $row->ProductionOrderID . "</td>";
            print "<td>" . $row->PONum . "</td>";
            print "<td>" . $row->OrderQTY . "</td>";
            print "<td>" . $row->BalLeftNum . "</td>";
            print "<td>" . $row->ProductionDate . "</td>";
            print "<td>" . $row->ProductionOrderStatusID . "</td>";
            print "<td>" . $row->NGID . "</td>";
            print "</tr>";
            print "</table>";
            //BatchOrder
            print "<table class='table table-striped'>";
            print "<tr> <th>Batch ID</th> <th>Brand Name</th> <th>Batch Quantity</th> <th>Availability Date</th> <th>Remaining Balance</th> <th>Production Order ID</th> </tr>";
            print "<td>" . $row->BatchID . "</td>";
            print "<td>" . $row->BrandID . "</td>";
            print "<td>" . $row->BatchQTY . "</td>";
            print "<td>" . $row->AvailDate . "</td>";
            print "<td>" . $row->RemainBal . "</td>";
            print "<td>" . $row->ProductionOrderID . "</td>";
            print "</tr>";
            print "</table>";
            //CustomerOrder
            print "<table class='table table-striped'>";
            print "<tr> <th>Customer ID</th> <th>Customer Name</th> <th>Invoice Quantity</th> <th>Invoice #</th> <th>Shipping Date</th> <th>Batch ID</th> <th>CO Status</th> </tr>";
            print "<td>" . $row->COID . "</td>";
            print "<td>" . $row->CustomerID . "</td>";
            print "<td>" . $row->InvoiceQTY . "</td>";
            print "<td>" . $row->InvoiceNum . "</td>";
            print "<td>" . $row->ShipDate . "</td>";
            print "<td>" . $row->BatchID . "</td>";
            print "<td>" . $row->COStatusID . "</td>";
            print "</tr>";
            print "</table>";
        }
    }
    else
    {
        print "No results to display!";
    }
}
$mysqli->close();
?>

This code currently produces this result: https://i.sstatic.net/FdCJL.png. This is almost the correct, intended behaviour... Each ProductionOrderID should generate a new table which has 2 child tables: BatchOrder and CustomerOrder. But it's currently only showing 1 result for each child table.

So to clarify, there can be any number of ProductionOrders created by the user (hence the foreach looping through the array). Each ProductionOrder can contain: Zero, One or Many BatchOrders and each BatchOrder can contain: Zero, One or Many CustomerOrders.

The current issue: As per the screenshot link just above, it is only displaying 1 BatchOrder and 1 CustomerOrder per ProductionOrder. My sample data contains multiple Batch Orders for ProductionOrderID=1 but they aren't displaying.

I am not sure if the issue is partly PHP and partly SQL related. I am new to both languages but I suspect LEFT JOIN is incorrect. However, it was the only method (currently) to display each ProductionOrder correctly with a BO and CO each... Just not all of them. I also suspect I need to execute another loop inside my existing while loop but I'm not sure on the correct approach as my current attempts have all been unsuccessful.

Detailed Information Here is a copy of my database SQL with sample data: https://pastebin.com/A3rt8kX4

Also my ERD to show intended behaviour: https://i.sstatic.net/5nlJu.png

Any help to not just help solve this current issue but to help me understand why it's wrong is absolutely appreciated.


EDIT: 1 I have fixed the keys joined in my SELECT statement but now only see one PO:

https://i.sstatic.net/p5b8s.png

SELECT * 
FROM ProductionOrder AS p
INNER JOIN ProductionOrderStatus AS s ON ( p.ProductionOrderID = s.ProductionOrderID ) 
INNER JOIN NotGood AS n ON ( p.ProductionOrderID = n.ProductionOrderID ) 
INNER JOIN BatchOrder AS b ON ( p.ProductionOrderID = b.ProductionOrderID )
INNER JOIN Brand AS bd ON ( b.BatchID = bd.BatchID ) 
INNER JOIN CustomerOrder AS co ON ( b.BatchID = co.BatchID ) 
INNER JOIN Customer AS c ON ( co.COID = c.COID ) 
INNER JOIN CustomerOrderStatus AS cos ON ( co.COID = cos.COID )
WHERE p.ProductionOrderID='$OrderId'") ) {

1 Answer 1

1

You need to join the primary key to the corresponding foreign key, for example:

LEFT JOIN ProductionOrderStatus AS s ON ( p.ProductionOrderID = s.ProductionOrderStatusID ) 

should be

LEFT JOIN ProductionOrderStatus AS s ON ( p.ProductionOrderID = s.ProductionOrderID )

You have the same issue in most of your joins.

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

1 Comment

Cheers for providing an example, I have corrected my SELECT statement. However, now I only see one iteration of the ProductionOrderID and still just 1 iteration of both the BatchOrder and CustomerOrders

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.