PHP 怎么Pivot

wen PHP项目 1

本文目录导读:

PHP 怎么Pivot

  1. 手动实现(基础方法)
  2. 使用数组函数(更完整的实现)
  3. 使用 Collection 类(Laravel 风格)
  4. 从数据库透视(MySQL + PHP)
  5. 高级透视函数(支持聚合)
  6. 完整的实用示例
  7. 注意事项

在 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'
]);
?>

注意事项

  1. 性能优化:大数据集时考虑使用数据库透视功能
  2. 错误处理:添加必要的数据验证
  3. 灵活性:根据需求选择合适的方法

选择哪种方式取决于你的具体需求和使用场景。

抱歉,评论功能暂时关闭!