【问题标题】:Can I limit the display of a resultset within PHP based on ID?我可以根据 ID 限制 PHP 中结果集的显示吗?
【发布时间】:2012-07-23 16:46:58
【问题描述】:

假设我有以下来自 mysql DB 调用的结果集(基本示例,main 将有更多数据):

customerID   |   name     |     item     |     price
====================================================
11111        |   John     |    pizza     |   10.00
11111        |   John     |    burger    |   5.00
11111        |   John     |    drink     |   2.00
22222        |   Mike     |    lasagna   |   11.00
22222        |   Mike     |    drink     |   2.00
33333        |   Sam      |    burger    |   5.00
33333        |   Sam      |    fries     |   3.00
33333        |   Sam      |    shake     |   5.00
33333        |   Sam      |    drink     |   2.00

我想以表格形式显示结果,但限制 customerID 和 name 出现的次数,以及按每个客户显示小计:

customerID   |    name    |   item    |    price
===================================================
11111        |    John    |  pizza    |   10.00
             |            |  burger   |   5.00
             |            |  drink    |   2.00
             |            |           |   **17.00**
             |            |           |
22222        |    Mike    |  lasagna  |   11.00
             |            |  drink    |   2.00
             |            |           |   **13.00**
             |            |           |
33333        |    Sam     |  burger   |   5.00
             |            |  fries    |   3.00
             |            |  shake    |   5.00
             |            |  drink    |   2.00
             |            |           |   **15.00**

我知道我可以进行多个数据库调用,但是如果可以一次性完成,那就太浪费了。我在通过表 1 中的结果集循环并使用 PHP 正确格式化时遇到问题,如表 2 所示。我是否有可能显示它的方式,或者我 必须 进行多个 DB 调用这样做?

【问题讨论】:

  • 您可以使用GROUP BY customerID, name WITH ROLLUP 语法(more about it)将组总数与普通行一起返回,因此不需要多次查询。我会在客户端代码中完成所有其他工作,因为它本质上是一个表示问题。
  • 不要做数据库端,这是基本的应用程序逻辑。只需遍历结果并创建一个具有所需结构的新数组。

标签: php mysql resultset


【解决方案1】:

这最好直接在 PHP 中解决,因为您可以随意修改输出。

所以基本上你会做类似(未经测试)的事情:

$res = mysql_query("SELECT costumerID, name, item, price
                    FROM orders 
                    ORDER BY customerID, item");

echo "<table id='orders'>".
      "<tr><th>Name</th>".
      "<th>Item</th>".
      "<th>Price</th></tr>";

$lastCostumer = -1;
$subTotal = 0; 
while ($row = mysql_fetch_array($res))
     {
     // New costumer
     if ($lastCostumer != $row['costumerID'])
           {
           // Write the subtotal of previous costumer, unless this is the 1st one
           if ($lastCostumer != -1)
              echo "<tr><td></td>".
                   "<td></td>".
                   "<td><b>**".$subTotal."**</b></td></tr>";

           $subTotal = 0; 
           echo "<tr><td>".$row['name']."</td>".
                "<td>".$row['item']."</td>".
                "<td>".$row['price']."</td></tr>";

           $subTotal = $subTotal + $row['price'];
           $lastCostumer = $row['costumerID'];
           }
     else // Same costumer
           {
           echo "<tr><td></td>".  // Don't write the name
                "<td>".$row['item']."</td>".
                "<td>".$row['price']."</td></tr>";

           $subTotal = $subTotal + $row['price'];
           }
     }

// Write the subtotal of last costumer
echo "<tr><td></td>".
     "<td></td>".
     "<td><b>**".$subTotal."**</b></td></tr>";

echo "</table>";

【讨论】:

  • 感谢您的建议 - 您的回答并未根据需要打印 customerID,但我明白了。在示例中,您的小计似乎会随着每个新客户继续增长,最终,它必须在 while results exists 循环内,并在每个客户开始时为空。
  • @JM4:不,“新客户”块中有一个$subTotal = 0; 行,它会重置计数器。
  • 得到它 - 正是我正在寻找的 - $lastCustomer = -1 是我缺少的部分。感谢您的帮助!
【解决方案2】:

您可以使用 group_concat() 来实现。

SELECT id, name, GROUP_CONCAT(item) AS items, GROUP_CONCAT(price) AS prices, SUM(price) AS total FROM ... GROUP BY id

在这里,您以逗号分隔的字符串形式获取商品和价格,并在另一列中获取总计。

group_concat 可以有它自己的顺序,更多信息看这个: http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat

【讨论】:

  • 可以使用GROUP_CONCAT,不是必须的,这个最好用PHP解决。
  • @ali - 感谢您的建议。我必须对其进行测试,但我基本上需要使用爆炸函数来分离项目并构建一个数组。最后,这似乎只是在做数据库已经做的工作​​,但我会更多地使用它。
【解决方案3】:

您可以进行一次数据库调用。只需循环遍历 PHP 中的结果并相应地输出表格。换句话说,我不认为这是一个数据库问题,而是一个决定如何循环遍历数据集和呈现 HTML 元素的问题。

【讨论】:

  • 我没有将其视为数据库问题。我的问题是直接询问如何使用 PHP 来实现这一点。使用 while 循环是有意义的,但对结果集进行排序是问题,因为 ID 将在每一行中返回(即只要 ID 与之前的行相同,执行 X,否则执行 Y)。
【解决方案4】:

您可以在(子)查询中使用 CONCAT_WS 运算符。使用'&lt;br/&gt;' 作为海分隔符。然后按客户 ID 分组。 但是,CONCAT_WS 的输出限制为 1024 个字符。

【讨论】:

  • 我试图不使用子查询,并且认为它们在这里没有必要。
  • 另外,SQL 直接输出 HTML 不是一个好主意,因为它很难管理
  • @JM4 你可以在没有子查询的情况下做到这一点。我刚刚添加了(子),因为我无法从这里看出你的数据库是什么样的......
  • @nico 您也可以使用逗号作为分隔符并将结果视为数组。用 foreach() 循环这个数组。这样您就不会获取不需要的数据。
  • @DirkMcQuickly:我更喜欢这个!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-12
相关资源
最近更新 更多