【问题标题】:Show total of values by month按月显示总值
【发布时间】:2021-04-16 17:13:03
【问题描述】:

我有一个显示发票及其创建日期的简单表格。我正在寻找一种在显示表格时在每个月的最后一行底部显示总发票值的方法。

例子:

Date Amount
04-05-2020 $50
02-05-2020 $30
14-05-2020 $10
TOTAL $90
Date Amount
04-07-2020 $15
02-07-2020 $15
14-07-2020 $15
TOTAL $45

有什么想法吗?这是我目前所拥有的:

<!DOCTYPE html>
<html>
<head>
<title>FACTURAS</title>

<style>
    
    table, th, td {
      border: 1px solid black;
    }

</style>
</head>
<body>

<?php

$server = "localhost";
$user = "root";
$password = "";
$db = "facturas";

$conn = new mysqli($server, $user, $password, $db);

if ($conn->connect_error) {

die("CONNECTION ERROR " . $conn->connect_error);
}

$sql = "SELECT * FROM facturas_table ORDER BY id";
$facturas = $conn->query($sql);

echo '<table>

<thead>

    <tr>

        <td>ID</td>
        <td>DATE</td>
        <td>INVOICE</td>
        <td>PRICE</td>

    </tr>

</thead>';

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

$month = substr($row['fecha'], 3);

// $totalMonths = "SELECT SUM(monto) as montoTotal FROM facturas_table WHERE fecha = ''"

echo '
<tbody>

    <tr>

        <td>'.$row['id'].'</td>
        <td>'.$row['fecha'].'</td>
        <td>'.$row['factura'].'</td>
        <td>'.$row['monto'].'</td>

    </tr>

</tbody>';
}

echo '</table>';

?>

</body>
</html>

【问题讨论】:

  • 跟mysqli有什么关系?
  • 确保只发布代码的相关部分 - 即 html 标题和样式真的无关紧要
  • 什么究竟不能使用所有这些代码?你有什么努力让它发挥作用?

标签: php mysqli html-table


【解决方案1】:

如果可能的话,首先尝试将 html 与 php 分开,因为混合会在未来产生问题。还要尝试对所有变量名使用英文(我假设 monto 是价格)。

我从您的问题中得到的是,您尝试创建表格并计算总数。因此,您将为总和创建一个变量,并将每行的当前数量添加到总和变量(在循环的每次迭代中)。

我更改了相关的php部分:

已更新您的评论(抱歉,您的问题不太清楚)。

重要的是 $lastMonth$month 以及 $first 的技巧


<tbody>
<?php
$total = 0; $lastMonth = ""; $first = true;
while ($row = $facturas->fetch_assoc()) : 
 $month = substr($row['fecha'], 3);
 $total += $row['monto']; ?>

<?php if(!$first && $lastMonth != $month): ?>
    <tr> 
        <th colspan="2">Total (<?=$month?>): </th>
        <th colspan="2"><?=$total?></th>
    </tr>
<?php $total=0; endif; ?>

    <tr>

        <td><?=$row['id']?></td>
        <td><?=$row['fecha']?></td>
        <td><?=$row['factura']?></td>
        <td><?=$row['monto']?></td>

    </tr>



<?php $first=false; $lastMonth = $month; endwhile; ?>


    <tr> 
        <th colspan="2">Total (<?=$month?>): </th>
        <th colspan="2"><?=$total?></th>
    </tr>
</tbody>


</table>

没有尝试过代码(所以一定要检查语法),但你可以知道如何很好地做到这一点

【讨论】:

  • 感谢您的回答。这接近我想要的。但我正在寻找的是按月显示总价格。请看一下问题中的示例。
  • 示例:4 月的 3 个价格、1 月的 2 个价格和 11 月的 5 个价格。我想在该月最后一行的底部显示每个月的总数。
  • 查看我的更新 - 也许你在你的问题中澄清一点
  • 这给了我一个想法,但我不知道如何测试这一点,因为你的 php 语法有点不同,我不确定我是否理解正确。跨度>
  • 请看一下我在问题中更新的图像。这就是我在尝试您的代码时得到的结果。
【解决方案2】:

虽然@helle 的答案侧重于 PHP 方面的解决方案,但这里是数据库方面的答案:

create table `facturas_table`(`id` bigint primary key, `invoice` varchar(100), `price` bigint, `date` date);
insert into `facturas_table` (`id`, `invoice`, `price`, `date`) values
    (1, "A25C45", 5000, str_to_date("04-05-2020", "%d-%m-%Y")),
    (2, "A25C46", 3000, str_to_date("02-05-2020", "%d-%m-%Y")),
    (3, "A25C47", 1000, str_to_date("14-05-2020", "%d-%m-%Y")),
    (4, "A25C48", 1500, str_to_date("04-07-2020", "%d-%m-%Y")),
    (5, "A25C49", 1500, str_to_date("02-07-2020", "%d-%m-%Y")),
    (6, "A25C50", 1500, str_to_date("14-07-2020", "%d-%m-%Y"))
;

select * from (
   select `id`, `invoice`, `price`, date_format(`date`, "%d-%m-%Y") `date`, date_format(`date`, "%Y-%m-%d") `ordering_format` from `facturas_table`
union all
   select null `id`, null `invoice`, `price`, `month` `date`, date_format(str_to_date(concat("01-", `month`), "%d-%m-%Y"), "%Y-%m-32") `ordering_format` from (
      select sum(`price`) `price`, date_format(`date`, "%m-%Y") `month` from `facturas_table` group by `month`
   ) `totals`
) `a` order by `ordering_format` asc;

从那里开始

<-- Some Code -->
<table>
   <thead>
      <tr>
         <th>ID</th>
         <th>DATE</th>
         <th>INVOICE</th>
         <th>PRICE</th>
      </tr>
   </thead>
   <tbody>
<?php while($row = $facturas->fetch_assoc()): ?>
   <?php if ($row["invoice"] === null): ?>
      <tr style="font-size: bolder">
         <td colspan="2">Total <?php echo $row["date"]; ?></td>
         <td colspan="2"><?php echo $row["price"]; ?></td>
      </tr>
   </tbody>
</table>
<table>
   <thead>
      <tr>
         <th>ID</th>
         <th>DATE</th>
         <th>INVOICE</th>
         <th>PRICE</th>
      </tr>
   </thead>
   <tbody>
   <?php else: ?>
      <tr>
         <td><?php echo $row["id"]; ?></td>
         <td><?php echo $row["date"]; ?></td>
         <td><?php echo $row["invoice"]; ?></td>
         <td><?php echo $row["price"]; ?></td>
      </tr>
   <?php endif; ?>
<?php endwhile; ?>
<-- Rest of Code -->

请注意,由于date 是 MySQL 中的保留关键字,因此它被包裹在反引号 (`) 中。最好将任何用户定义的名称(即使它们未保留)包含在反引号中,以避免混淆和不必要且难以捕捉的语法错误。

另请注意,价格以美分表示,其类型为bigint。这也是一种很好的做法:

  1. 使用bigint 表示从长远来看会非常庞大​​并且很可能在未来也被归档到仓库中的表的整数主键。这样,您在轮换 ID 之前有足够的时间,最好使用一些长期保证的唯一值,例如 UUIDs 和 GUIDs 作为主键。在这种情况下,如果发票编号是唯一的,最好选择 ID 作为 ID,因为它是此类记录的自然 ID。
  2. 使用目标市场中尽可能小的货币,这样您将避免使用小数(效率低下)或最差的浮点数(精度很差,因为计算机以 2 为基数工作,而人类以 10 为基数工作) .此外,如果您需要除以任何货币价值(例如计算回扣和折扣),请始终对最小货币使用相同的舍入策略。例如,如果您要对 9.95 美元的商品提供 10% 的折扣,您可以选择向上四舍五入的政策(避免客户不满意),但始终坚持下去,也使用BCD 操作因为它们像人类一样计算价值,而不像计算机那样计算价值,但价格昂贵。在像这样容易出错的敏感情况下使用它们(不仅仅是简单的整数相加,而是除法和乘法)
$price = 995;
$discount = 10;
$discounted_value = explode(".", bcdiv(bcmul($price, $discount, 2), "100", 2), 2);
$discounted_value = $discounted_value[0] + (($discounted_value[1] + 0) !== 0);
$final_price = $price - $discounted_value;

最后,如果您认为您要处理的价格高于PHP_INT_MAX(注意 32 位和 64 位版本不同),只需进入完全狂暴模式并结合使用字符串 bcmath价格操作。

拥有良好的在线业务!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-23
    • 1970-01-01
    • 2020-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多