首页 > 解决方案 > PHP处理数据并创建数组

问题描述

我有一个mysql查询,结果如下:

ID | index | Mapping index |   Date   
1  |  27   |    value27    |   2019-04      
2  |  28   |    value28    |   2019-05       
3  |  28   |    value28    |   2019-05      
4  |  32   |    value32    |   2019-07    
5  |  32   |    value32    |   2019-05  

结果应准备好显示堆叠图表。结果我需要在php中:

// array to display google chart
['2019-04', 1, 0, 0,],
['2019-05', 0, 2, 1,],
['2019-07', 0, 0, 1,],

// explanation
ID | value27 | value28 | value 32 |  Date   
1  |  1      |  0      | 0        |  2019-04      
2  |  0      |  2      | 1        |  2019-05   
2  |  0      |  0      | 1        |  2019-07  

这是我的 php 脚本:

$preparevar = array();
foreach($data["timechart"] as $date){
    array_push($preparevar,[$date->date, $date->count , '\''.$date->repcontent.'\'' ]);
} 

$googleChartArray = array(); //Use this array to group the results using date.
foreach( $preparevar as $d ) {
    $date = $d[0];
    $value = $d[1];

    if( !isset( $googleChartArray[$date] ) ) {
        $googleChartArray[$date] = array( "'". $date. "'" ); //Date needs to be enclosed in quote.
    }
    $googleChartArray[$date][] = $value; 
}

$f = array(); //Format the above array to split value in a comma separated format.
foreach( $googleChartArray as $g ) {
    $f[] = implode( ',' , $g );
}

$json_out = json_encode(array_values($googleChartArray));

这种格式的问题是,零值将被忽略:

[
['2019-04',1],
['2019-05',2,1],
['2019-07',1]
]  

应该:

[
['2019-04',1,0,0],
['2019-05',0,2,1],
['2019-07',0,0,1]
]       

这里是 $data["timechart"] 的示例:

array(11) {
  [0]=>
  object(stdClass)#43 (14) {
    ["id"]=>
    string(2) "46"
    ["index"]=>
    string(2) "31"
    ["index2"]=>
    string(1) "0"
    ["keynr"]=>
    string(2) "31"
    ["repcontent"]=>
    string(41) "Value31"
    ["count"]=>
    string(1) "1"
    ["date"]=>
    string(7) "2007-06"
  }

这是我的查询示例。例如,我不能使用 SUM(CASE),因为索引是可变的。

SELECT
        orders.id,
        positions_list.index,
        RepK.keynr,
        RepK.content AS repcontent,
        RepK.p_company,
        COUNT(positions_list.index) AS count,
        DATE_FORMAT(orders.date_placement, '%Y-%m') AS date
        from orders
        JOIN tools
        ON tools.id=orders.tool_id
        JOIN positions_list ON positions_list.order_id = orders.id
        LEFT JOIN repkey as RepK
        ON   RepK.keynr=positions_list.index
        AND  RepK.p_company=orders.comp_id

        WHERE
        tools.id =:id
        AND RepK.keynr IS NOT NULL

        group by DATE_FORMAT(orders.date_placement, '%Y-%m'),positions_list.index

标签: phpmysqlarrays

解决方案


MySQL 目前不提供可变宽度的枢轴,因此您可以:

  1. 进行两个查询,第一个是收集唯一的 repcontent 列,然后构建第二个查询以通过为每个列编写带有动态 CASE WHEN 语句的 SELECT 子句来实现枢轴技术,或者
  2. 进行一次查询,然后让 php 准备结果(这可以用几种不同的方式编写脚本,但我会推荐这个)

代码:(演示

$resultSet = [
    ['repcontent' => 'Value 27', 'date' => '2019-04'],
    ['repcontent' => 'Value 28', 'date' => '2019-05'],
    ['repcontent' => 'Value 28', 'date' => '2019-05'],
    ['repcontent' => 'Value 32', 'date' => '2019-07'],
    ['repcontent' => 'Value 32', 'date' => '2019-05'],
];

$columns = array_unique(array_column($resultSet, 'repcontent'));
$lookupKeys = range(1, count($columns));
$lookup = array_combine($columns, $lookupKeys);
$defaults = array_fill_keys($lookupKeys, 0);

foreach ($resultSet as $row) {
    if (!isset($result[$row['date']])) {
        $result[$row['date']] = array_merge([$row['date']], $defaults);
    }
    ++$result[$row['date']][$lookup[$row['repcontent']]];
}
echo json_encode(array_values($result));

输出:

[["2019-04",1,0,0],["2019-05",0,2,1],["2019-07",0,0,1]]

为简单起见,将结果集生成为数组数组。

  1. 提取唯一repcontent
  2. 生成一个值从 1 到唯一repcontent计数的数组
  3. 伪造一个包含 #1 作为键和 #2 作为值的查找数组——这将确定每个“计数”在以后循环时将存储在哪里
  4. 创建一个默认数组,其中包含 #2 作为键和零作为值
  5. 现在,遍历结果集,如果给定的行有一个repcontent第一次遇到的值,则在输出数组中创建一个新行,使用date作为第一个元素和 #4 中的元素跟随。
  6. 无条件将与该repcontent值对应的行的列加1

如果您不太明白为什么会生成任何变量 ( $columns, $lookupKeys, $lookup, $defaults) 或它们包含什么,请var_export()在进入循环之前调用我的变量——这应该可以消除任何混淆。

我有一种感觉,我可以改进您的查询,但如果没有一些真实的样本数据可供使用,我不会冒险猜测。

我不明白为什么您需要在 json 中添加额外的引号才能使 Google 图表正常工作。如果在没有附加引号的情况下图表无法呈现,这可能是您以不正确的方式将 php 变量传递给 javascript 的症状。

ps 我看到您使用 Joomla 进行了一些开发,如果这是一个 Joomla 脚本并且您无法使用 Joomla 的查询构建方法来制作您的查询,请在Joomla Stack Exchange上发布您的最大努力,我会看看我是否可以提供帮助。


推荐阅读