2016-08-02 64 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