2016-08-02 60 views
1

我有一個名爲item_movement其中I存儲購買,出售的庫存數表,通過顧客返回或返回到供應商:是否可以加上或減去前一個循環的值?

------------------------------------------------------------------------ 
| trans_id | date  | trans_type  | inventory_id | quantity | 
------------------------------------------------------------------------ 
|  1 | 2016-07-26 | Purchase   |  1  | 10  | 
------------------------------------------------------------------------ 
|  2 | 2016-07-26 | Purchase   |  2  |  8  | 
------------------------------------------------------------------------ 
|  3 | 2016-07-27 | Sale    |  1  |  2  | 
------------------------------------------------------------------------ 
|  4 | 2016-07-28 | Customer Return |  1  |  1  | 
------------------------------------------------------------------------ 
|  5 | 2016-07-29 | Supplier Pullout |  2  |  5  | 
------------------------------------------------------------------------ 

的inventory_id是每個清單的識別。

我的代碼是:

$conn = new mysqli('localhost', 'username', 'password', 'database'); 
$query = $_GET['id']; 
$item_stock = $conn->query("SELECT * FROM item_movement WHERE `inventory_id` = '%".$query."%' ORDER BY date DESC") or die(mysql_error()); 

echo '<table class="stock-info-table"> 
      <tr class="center"> 
      <th>Date</th> 
      <th>Transaction Type</th> 
      <th>Quantity</th> 
      <th>Running Stock</th> 
      </tr>'; 
while($row = mysqli_fetch_array($item_stock)){ 
     echo '<tr> 
      <td>'.$row['date'].'</td> 
      <td>'.$row['trans_type'].'</td> 
      <td>'.$row['quantity'].'</td> 
      <td>RUNNING STOCK HERE</td> 
     </tr>'; 
} 
echo '</table>'; 

問題: 我還沒有想出如何顯示正在運行的股票,你可以在我的代碼中看到。正在運行的庫存欄應顯示每筆交易的庫存移動數量,如庫存ID 1的採購數量爲10,則應顯示10。如果銷售數量爲2,則應顯示8(10-2)。基本上該股票的公式爲:購買 - 銷售+客戶退貨 - 供應商拉出。 數據還應該顯示最近的交易優先級(DESC),其中運行庫存的順序也應該以此爲基礎。

編輯: 下面是一個例子的數據,我想顯示的inventory_id:

------------------------------------------------------------------- 
| Date  | Transaction Type | Quantity | Running Stock | 
------------------------------------------------------------------- 
| 2016-07-29 | Purchase   |  5  |  12  | 
------------------------------------------------------------------- 
| 2016-07-28 | Supplier Pullout |  2  |  7  | 
------------------------------------------------------------------- 
| 2016-07-27 | Customer Return |  1  |  9  | 
------------------------------------------------------------------- 
| 2016-07-26 | Sale    |  2  |  8  | 
------------------------------------------------------------------- 
| 2016-07-25 | Purchase   |  10  |  10  | 
------------------------------------------------------------------- 

讓我知道這是可能的。

+1

我認爲如果您向我們提供您提供的表格的預期輸出,將會有所幫助。我仍然不確定你是如何計算股票的。 – FrankerZ

+0

_Side注意:_不要使用LIKE作爲此選擇使用'inventory_id = $ query' LIKE用於將字符串的位與長字符串進行匹配 – RiggsFolly

+0

您還將向我們展示如何獲得當前' IN_STOCK'值 – RiggsFolly

回答

2

您可以通過將變量中的庫存總量保持運行來實現此目的。

我假設你有當前股票持有的地方,但這個例子將開始價值爲零的演示目的。

同樣使用mysqli_fetch_assoc(),因爲它只返回一個assoc列數組而不是數組數組。

$cur_stock = 0; 

$id= $_GET['id']; 
$item_stock = $conn->query("SELECT * 
          FROM `item_movement` 
          WHERE `inventory_id` = $id 
          ORDER BY date ASC") 
       or die(mysql_error()); 

echo '<table class="stock-info-table"> 
      <tr class="center"> 
      <th>Date</th> 
      <th>Transaction Type</th> 
      <th>Quantity</th> 
      <th>Running Stock</th> 
      </tr>'; 

while($row = $conn->fetch_assoc($item_stock)){ 

    switch ($row['trans_type']) { 
     case 'Purchase' : 
     case 'Customer Return' : 
      $cur_stock += (int)$row['quantity']; 
      break; 

     case 'Sale' : 
     case 'Supplier Pullout' : 
      $cur_stock -= (int)$row['quantity']; 
      break; 
    } 

    echo '<tr> 
      <td>'.$row['date'].'</td> 
      <td>'.$row['trans_type'].'</td> 
      <td>'.$row['quantity'].'</td> 
      <td>' . $cur_stock . '</td> 
      </tr>'; 
} 
echo '</table>'; 

這將是更好地使用prepared statement and parameterized statements

這方面的一個例子是

$cur_stock = 0; 

$id= $_GET['id']; 

$stmt = $conn->prepare("SELECT * 
         FROM `item_movement` 
         WHERE `inventory_id` = ? 
         ORDER BY date ASC"); 
if ($stmt === false) { 
    echo $conn->error; 
    exit; 
} 
$stmt->bind_param('i', $id); 

$status = $stmt->execute(); 
if ($status === false) { 
    echo $conn->error; 
    exit; 
} 

$result = $stmt->get_result(); 

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

    switch ($row['trans_type']) { 
     case 'Purchase' : 
     case 'Customer Return' : 
      $cur_stock += (int)$row['quantity']; 
      break; 

     case 'Sale' : 
     case 'Supplier Pullout' : 
      $cur_stock -= (int)$row['quantity']; 
      break; 
    } 

    echo '<tr> 
      <td>'.$row['date'].'</td> 
      <td>'.$row['trans_type'].'</td> 
      <td>'.$row['quantity'].'</td> 
      <td>' . $cur_stock '</td> 
      </tr>'; 
} 
echo '</table>'; 

得到你想要的,即逆轉將是暫時的輸出的最簡單方法將結果存儲在數組中,然後在輸出HTML表之前反轉數組。

$temp = array(); 
while($row = $result->fetch_assoc($item_stock)){ 

    switch ($row['trans_type']) { 
     case 'Purchase' : 
     case 'Customer Return' : 
      $cur_stock += (int)$row['quantity']; 
      break; 

     case 'Sale' : 
     case 'Supplier Pullout' : 
      $cur_stock -= (int)$row['quantity']; 
      break; 
    } 
    $row['running_stock'] = $cur_stock; 
    $temp[] = $row; 
} 
// reverse the array 
$temp2 = array_reverse($temp); 

foreach($temp2 as $row) { 
    echo '<tr> 
      <td>' . $row['date']   .'</td> 
      <td>' . $row['trans_type'] .'</td> 
      <td>' . $row['quantity']  .'</td> 
      <td>' . $row['running_stock'] .'</td> 
      </tr>'; 
} 
echo '</table>'; 
+0

@OP發佈了他的連接代碼。我認爲如果你改寫連接以使用綁定語句,那將是最好的。 – FrankerZ

+0

應該是'echo $ conn-> error;' – FrankerZ

+0

@RiggsFolly這個工作很好,除了跑步股票是以遞增的方式而不是遞減的。 – hello

1

爲了清楚起見,我保留此答案(如果OP需要獲取庫存項目的庫存數量),但不幸的是這對於OP所尋找的不起作用。這將獲得股票,但不會增加正在運行的股票,因爲事情被添加/刪除。請參閱@ RiggsFolly關於如何做到這一點的答案。

通過在mysql中使用GROUP BY和聚合函數,可以按事務類型總計總和。該查詢應該給你,你要尋找的股票:

SELECT `inventory_id`, SUM(
    CASE 
     WHEN trans_type IN ('Purchase', 'Customer Return') THEN quantity 
     WHEN trans_type IN ('Customer Return', 'Supplier Pullout') THEN -1 * quantity 
    END 
) AS `stock` 
    FROM item_movement 
    WHERE `inventory_id` LIKE '%".$query."%' 
    GROUP BY inventory_id 
    ORDER BY date DESC 

運行一組通過查詢第一,拿到股票,然後填充數組。在第二個循環中,引用第一個數組。你在這裏更新代碼:

<?php 
$query = $_GET['id']; 

//DO NOT CONCAT QUERY HERE. VERY BAD (See my comment below) 
$running_stock = $conn->query(" 
    SELECT `inventory_id`, SUM(
    CASE 
     WHEN trans_type IN ('Purchase', 'Customer Return') THEN quantity 
     WHEN trans_type IN ('Customer Return', 'Supplier Pullout') THEN -1 * quantity 
    END 
) AS `stock` 
    FROM item_movement 
    WHERE `inventory_id` LIKE '%".$query."%' 
    GROUP BY `inventory_id`") or die(mysqli_error()); 

$running_stocks = array(); 

while($row = mysqli_fetch_array($running_stock)){ 
    $running_stocks[ $row['inventory_id'] ] = $row['stock']; 
} 
//DO NOT CONCAT QUERY HERE. VERY BAD (See my comment below) 
$item_stock = $conn->query("SELECT * FROM item_movement WHERE `inventory_id` LIKE '%".$query."%' ORDER BY date DESC") or die(mysqli_error()); 

echo '<table class="stock-info-table"> 
      <tr class="center"> 
      <th>Date</th> 
      <th>Transaction Type</th> 
      <th>Quantity</th> 
      <th>Running Stock</th> 
      </tr>'; 
while($row = mysqli_fetch_array($item_stock)){ 
    echo '<tr> 
      <td>'.$row['date'].'</td> 
      <td>'.$row['trans_type'].'</td> 
      <td>'.$row['quantity'].'</td> 
      <td>'.(isset($running_stocks[$row['inventory_id']]) ? $running_stocks[$row['inventory_id']] : 0).'</td> 
     </tr>'; 
} 
echo '</table>'; 

請注意:你應該binding parameters to your queries以防止SQL注入。

1

你應該可以用純SQL解決方案來做到這一點。

如果您將自己的表格加入其中,那麼匹配的行越早,那麼您可以使每行都包含所有較舊的數量。然後,您可以使用SUM來累加較舊的數量以獲得運行總數。

由於您的一些數量可能會有效爲負值,具體取決於的交易類型您需要在SUM聚合函數內有條件地乘以-1。

SELECT a.`Date`, 
     a.`Transaction Type`, 
     a.`Quantity`, 
     SUM 
     (
      CASE b.`Transaction Type` 
       WHEN 'Supplier Pullout' 
       THEN b.`Quantity` * -1 
       WHEN 'Sale' 
       THEN b.`Quantity` * -1 
       ELSE b.`Quantity` 
      END 
     ) AS `Running Stock` 
FROM item_movement a 
INNER JOIN item_movement b 
ON a.inventory_id = b.inventory_id 
AND a.`date` >= b.date 
WHERE a.inventory_id = '%".$query."%' 
GROUP BY a.`Date`, 
     a.`Transaction Type`, 
     a.`Quantity` 
ORDER BY a.`date` DESC