本文目录导读:

在 PHP 中实现数据透视(Pivot)有多种方式,这里分享几种常见方案:
手动实现(基础方法)
<?php
// 原始数据
$data = [
['month' => 'Jan', 'product' => 'A', 'sales' => 100],
['month' => 'Jan', 'product' => 'B', 'sales' => 150],
['month' => 'Feb', 'product' => 'A', 'sales' => 120],
['month' => 'Feb', 'product' => 'B', 'sales' => 180],
['month' => 'Mar', 'product' => 'A', 'sales' => 110],
['month' => 'Mar', 'product' => 'B', 'sales' => 160],
];
// 手动透视
$pivot = [];
foreach ($data as $row) {
$pivot[$row['month']][$row['product']] = $row['sales'];
}
// 输出结果
foreach ($pivot as $month => $products) {
echo $month . ": ";
foreach ($products as $product => $sales) {
echo "$product=$sales ";
}
echo "\n";
}
?>
使用数组函数(更完整的实现)
<?php
function pivotTable($data, $rowKey, $colKey, $valueKey) {
$result = [];
$columns = [];
// 收集所有列标题
foreach ($data as $row) {
$columns[$row[$colKey]] = true;
}
// 构建透视表
foreach ($data as $row) {
$r = $row[$rowKey];
$c = $row[$colKey];
$v = $row[$valueKey];
if (!isset($result[$r])) {
$result[$r] = array_fill_keys(array_keys($columns), 0);
}
$result[$r][$c] = $v;
}
return $result;
}
// 使用示例
$data = [
['month' => 'Jan', 'product' => 'A', 'sales' => 100],
['month' => 'Jan', 'product' => 'B', 'sales' => 150],
['month' => 'Feb', 'product' => 'A', 'sales' => 120],
['month' => 'Feb', 'product' => 'B', 'sales' => 180],
];
$result = pivotTable($data, 'month', 'product', 'sales');
print_r($result);
?>
使用 Collection 类(Laravel 风格)
<?php
class Collection {
private $items;
public function __construct($items) {
$this->items = $items;
}
public function pivot($groupBy, $column, $value) {
$result = [];
foreach ($this->items as $item) {
$group = $item[$groupBy];
$col = $item[$column];
$val = $item[$value];
if (!isset($result[$group])) {
$result[$group] = [];
}
$result[$group][$col] = $val;
}
return $result;
}
}
// 使用
$collection = new Collection($data);
$pivoted = $collection->pivot('month', 'product', 'sales');
?>
从数据库透视(MySQL + PHP)
<?php
// MySQL 透视查询
$sql = "SELECT
month,
SUM(CASE WHEN product = 'A' THEN sales ELSE 0 END) AS product_A,
SUM(CASE WHEN product = 'B' THEN sales ELSE 0 END) AS product_B
FROM sales_data
GROUP BY month";
$result = $pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC);
?>
高级透视函数(支持聚合)
<?php
function advancedPivot($data, $index, $columns, $values, $aggregation = 'sum') {
$result = [];
foreach ($data as $row) {
$idxVal = $row[$index];
$colVal = $row[$columns];
if (!isset($result[$idxVal])) {
$result[$idxVal] = [];
}
// 聚合操作
switch ($aggregation) {
case 'sum':
$result[$idxVal][$colVal] =
($result[$idxVal][$colVal] ?? 0) + $row[$values];
break;
case 'count':
$result[$idxVal][$colVal] =
($result[$idxVal][$colVal] ?? 0) + 1;
break;
case 'avg':
$result[$idxVal]['_count_' . $colVal] =
($result[$idxVal]['_count_' . $colVal] ?? 0) + 1;
$result[$idxVal][$colVal] =
($result[$idxVal][$colVal] ?? 0) + $row[$values];
break;
}
}
// 计算平均值
if ($aggregation == 'avg') {
foreach ($result as &$row) {
foreach ($row as $key => $value) {
if (strpos($key, '_count_') !== 0 && isset($row['_count_' . $key])) {
$row[$key] = $value / $row['_count_' . $key];
}
}
unset($row['_count_']);
}
}
return $result;
}
?>
完整的实用示例
<?php
class PivotHelper {
public static function create($data, $options) {
$defaults = [
'rowKey' => 'month',
'colKey' => 'product',
'valueKey' => 'sales',
'aggregation' => 'sum',
'fillValue' => 0
];
$options = array_merge($defaults, $options);
$result = [];
$columns = [];
// 获取所有列
foreach ($data as $row) {
if (isset($row[$options['colKey']])) {
$columns[$row[$options['colKey']]] = true;
}
}
// 构建透视表
foreach ($data as $row) {
$rowVal = $row[$options['rowKey']] ?? '';
$colVal = $row[$options['colKey']] ?? '';
$val = $row[$options['valueKey']] ?? 0;
if (!isset($result[$rowVal])) {
$result[$rowVal] = array_fill_keys(array_keys($columns), $options['fillValue']);
}
// 聚合
switch ($options['aggregation']) {
case 'sum':
case 'avg':
$result[$rowVal][$colVal] += $val;
break;
case 'count':
$result[$rowVal][$colVal] += 1;
break;
case 'max':
$result[$rowVal][$colVal] = max($result[$rowVal][$colVal], $val);
break;
case 'min':
$result[$rowVal][$colVal] = min($result[$rowVal][$colVal], $val);
break;
}
}
return $result;
}
}
// 使用
$pivot = PivotHelper::create($data, [
'rowKey' => 'month',
'colKey' => 'product',
'valueKey' => 'sales',
'aggregation' => 'sum'
]);
?>
注意事项
- 性能优化:大数据集时考虑使用数据库透视功能
- 错误处理:添加必要的数据验证
- 灵活性:根据需求选择合适的方法
选择哪种方式取决于你的具体需求和使用场景。