我正在使用从SQL查询中提取的数据稍后在代码中构建两个图表。查询示例如下:
SELECT purchase_location, purchase_item, SUM(purchase_amount) as totalPurchase
FROM purchases
GROUP BY purchase_item_id, purchase_location
不是一个确切的例子,但是想法就在那里。然后,我遍历结果以构建两个数据集。
$locationData = [];
$itemData = [];
foreach($queryResults as $result) {
$locationData[$result['purchase_location']] += $result['totalPurchase'];
$itemData[$result['purchase_item']] += $result['totalPurchase'];
}
由于我希望从两个不同的角度来看数据,因此我必须使用+ =来获得正确的总数。我的问题是这样的:对数组的未设置索引执行+ =运算符非常慢。我发现如果执行以下操作:
if (isset($locationData['purchase_location'])) {
$locationData['purchase_location'] += $result['totalPurchase'];
} else {
$locationData['purchase_location'] = $result['totalPurchase'];
}
第一次使用=来查看索引。这样可以大大加快代码的速度(例如,我的代码从8-10秒的运行时间缩短到不到半秒)。我的问题是,这是正确/最干净的方法吗?
在任何人提到之前,我都知道我可以在这种简单情况下编写查询来处理所有这些问题,这只是一个非常简单的例子来说明问题,即在尚未定义的情况下使用+ =数组索引。
答案 0 :(得分:1)
我建议已经使用该索引初始化数组,避免进行isset检查并使代码更简洁:
$locationData = ['purchase_location' => 0];
$itemData = ['purchase_item' => 0];
foreach($queryResults as $result) {
$locationData['purchase_location'] += $result['totalPurchase'];
$itemData['purchase_item'] = $result['totalPurchase'];
}
对于我的项目,我通常尝试将isset的使用范围限制为验证无法完全控制的外部来源(例如GET,POST)接收的数据。
既然您已经更新了答案,现在可以在这种情况下使用isset
来避免另一个循环来构造数组。
$locationData = [];
$itemData = [];
foreach($queryResults as $result) {
if (!isset($locationData[$result['purchase_location']])) {
$locationData[$result['purchase_location']] = 0;
}
if (!isset($itemData[$result['purchase_item']])) {
$itemData[$result['purchase_item']] = 0;
}
$locationData[$result['purchase_location']] += $result['totalPurchase'];
$itemData[$result['purchase_item']] += $result['totalPurchase'];
}
如果您使用的是PHP 7+,则可以使用null coalesce ??
来简化代码,如下所示:
$locationData = [];
$itemData = [];
foreach($queryResults as $result) {
$locationData[$result['purchase_location']] = $result['totalPurchase'] + ($locationData[$result['purchase_location']] ?? 0);
$itemData[$result['purchase_item']] = $result['totalPurchase'] + ($itemData[$result['purchase_item']] ?? 0);
}
答案 1 :(得分:1)
您可以尝试以下操作:
$locationData = [];
$itemData = [];
foreach($queryResults as $result) {
$locationData[$result['purchase_location']] = ($locationData[$result['purchase_location']]??0) + $result['totalPurchase'];
$itemData[$result['purchase_item']] = ($itemData[$result['purchase_item']]??0) + $result['totalPurchase'];
}
但是我认为将所有内容分别初始化为零是更干净,更明显的方法:
foreach($queryResults as $result) {
$locationData[$result['purchase_location']] = 0;
$itemData[$result['purchase_item']] = 0;
}
,然后在另一个循环中进行加法工作。
答案 2 :(得分:0)
对于您的问题,是的,您需要先创建此索引,然后再向该索引添加+ =。
而不是每次迭代都检查它,因此只需在foreach循环之前对其进行配置,然后该索引将退出,您将能够对+ =和多数民众赞成进行累加
HashMap
答案 3 :(得分:0)
我的问题是,这是正确/最干净的处理方式吗?
没有示例数据和预期结果,很难知道您追求的结果。
有根据的猜测是使用MySQL WITH ROLLUP
GROUP BY Modifier来获得总记录。
SELECT purchase_location, purchase_item, SUM(purchase_amount) as totalPurchase
FROM purchases
GROUP BY purchase_item_id, purchase_location WITH ROLLUP