PHP - 将多个项目合并为一个

3

我正在尝试创建一个最终用户页面,展示可用于检查的不同服务器。任何时候,服务器可以具有“可用”状态或“保留”状态。我使用MySQL后端。这是我的查询方式:

SELECT *, COUNT(CASE WHEN Status = 'Available' THEN 1 ELSE NULL END) AS Amount
FROM products GROUP BY id

这是我得到的结果:
id,Server_Type,Status,Amount
1,BL460,Available,1
2,BL460,Available,1
3,BL460,Reserved,0
4,BL460,Reserved,0
5,BL460,Reserved,0
6,DL360,Available,1
7,DL360,Reserved,0
8,DL360,Reserved,0

Reserved 等于0,而 Available 等于1 时,我只希望最终用户能够结账一个处于 Available 状态的服务器。

对于这个问题:我在页面上想要以此方式呈现服务器列表,其中 Available 等于数量:

BL460 - Amount: 2
DL360 - Amount: 1

我该如何在PHP中实现此格式?

1
你应该始终使用反引号标记你的标识符,因此用反引号括起来StatusAmountproductsid。这将使你的查询保持有效,即使在 MySQL 服务器更新时引入新保留字与你的标识符冲突。 - Shi
2个回答

1
另一个选项是交叉表查询 -
SELECT `Status`,
SUM(IF(`Server_Type` = 'BL460' AND `Status` = 'Available', `Amount`, 0)) AS `BL460`,
SUM(IF(`Server_Type` = 'DL360' AND `Status` = 'Available', `Amount`, 0)) AS `DL360`
FROM `products`
GROUP BY `Status`

你的表格应该长这样 -
Status    |    BL460    |    DL360    |
Available |        2    |        1    |
Reserved  |        0    |        0    |

这里有一个示例

更好的方法是反过来 -

SELECT `server_type`,
SUM(IF(`status` = 'Available', 1, 0)) AS `Available`,
SUM(IF(`status` = 'Reserved', 1, 0)) AS `Reserved`
FROM `servers`
GROUP BY `server_type`;

这将导致一个表格,看起来像这样(基于fiddle中的数据)-
server_type    |    Available    |    Reserved
BL460          |            3    |           1
DL360          |            1    |           2

这里是例子

在第一个查询中,如果要继续向表中添加服务器,就必须担心将它们添加到查询中。而在第二个查询中,则可以继续向表中添加服务器,而不必担心这一点。如果添加了其他状态,则必须更改查询。

请注意,在这两种情况下,没有必要使用Amount,因为状态就是计数的项。通过将负载放在数据库服务器上,输出HTML变得更加容易,因为您只需像通常一样逐行进行即可。


谢谢!让我也看看这个方法。我会很快回报。 - Wes
嗨Jay - 这个问题是我会失去“id”列,而我需要保留它以使每个项目保持唯一。 - Wes
如果您查看示例,仍然有一个id列,因此没有任何唯一性丢失 @Wes - Jay Blanchard

0

嗯,如果您直接在SQL查询中执行操作,那可能会更容易:

SELECT Server_Type, COUNT(*) AS Count FROM products WHERE Status = 'Available' GROUP BY Server_Type

这应该会给你想要的表格。

如果你想用PHP实现,最简单的解决方案可能是通过循环遍历SQL结果,并在一个关联数组中计算每个Server_Type可用服务器的数量,其中Server_Type是你的数组键:

$amounts = array();

foreach($sql_result as $entry) {
    if($entry['Amount'] == 1) {
        if(isset($amounts[$entry['Server_Type']])) {
            $amounts[$entry['Server_Type']]++;
        } else {
            $amounts[$entry['Server_Type']] = 1;
        }
    }
}

echo $amounts;

编辑:为了按照问题描述打印值,您可以使用以下代码片段:

foreach($amounts as $name=>$amount) {
    echo $name + " - Amount: " + $amount + "<br>";
}

我无法按Server_Type分组,因为这样每个独特的项目都无法被表示。在结账阶段,我需要每个最终用户选择的“id”从“可用”状态更改为“已预订”状态。如果没有对每个唯一id的了解,我不确定如何完成这项任务。 - Wes
@Wes 好的,那么你需要分别执行两个 SELECT 语句来实现这个功能。作为替代方案,可以看一下我刚刚添加的基于 PHP 的解决方案;它是否符合你的要求? - TimoStaudinger
是的 - 你基本上回答了我的问题。但是为了进一步说明,我如何表示Server_Type和Amount作为我可以输入到页面的单独值?这条路使一切成为一个结果。我尝试做的事情甚至有必要吗?在我的结帐过程中,我可以进行单独的SELECT来实现我所需的吗?编辑:刚看到你的新帖子TimoSta,但它没有起作用。 - Wes
你看了我的编辑吗?实际上,这个解决方案为你提供了每种Server_Type的可用数量和Server_Type。 - TimoStaudinger
抱歉,我没有足够的信息来回答一个单独的SELECT语句在结账时是否足够。在当前页面上,您希望用户能够选择特定ID的某个条目,还是只选择具有特定服务器类型的任何条目? - TimoStaudinger
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接