php - 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
解决方案
MySQL 目前不提供可变宽度的枢轴,因此您可以:
- 进行两个查询,第一个是收集唯一的 repcontent 列,然后构建第二个查询以通过为每个列编写带有动态 CASE WHEN 语句的 SELECT 子句来实现枢轴技术,或者
- 进行一次查询,然后让 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]]
为简单起见,将结果集生成为数组数组。
- 提取唯一
repcontent
值 - 生成一个值从 1 到唯一
repcontent
计数的数组 - 伪造一个包含 #1 作为键和 #2 作为值的查找数组——这将确定每个“计数”在以后循环时将存储在哪里
- 创建一个默认数组,其中包含 #2 作为键和零作为值
- 现在,遍历结果集,如果给定的行有一个
repcontent
第一次遇到的值,则在输出数组中创建一个新行,使用date
作为第一个元素和 #4 中的元素跟随。 - 无条件将与该
repcontent
值对应的行的列加1
如果您不太明白为什么会生成任何变量 ( $columns
, $lookupKeys
, $lookup
, $defaults
) 或它们包含什么,请var_export()
在进入循环之前调用我的变量——这应该可以消除任何混淆。
我有一种感觉,我可以改进您的查询,但如果没有一些真实的样本数据可供使用,我不会冒险猜测。
我不明白为什么您需要在 json 中添加额外的引号才能使 Google 图表正常工作。如果在没有附加引号的情况下图表无法呈现,这可能是您以不正确的方式将 php 变量传递给 javascript 的症状。
ps 我看到您使用 Joomla 进行了一些开发,如果这是一个 Joomla 脚本并且您无法使用 Joomla 的查询构建方法来制作您的查询,请在Joomla Stack Exchange上发布您的最大努力,我会看看我是否可以提供帮助。
推荐阅读
- pandas - 复制特定行并分离 str 列值 pandas
- python - Python 应用程序无法使用 Pygame (python3) 打开
- python - Python 谷歌新闻脚本
- mysql - GROUP BY 另一个已经用两个子查询分组的表
- javascript - Reactjs 记录器-js 下载
- sql - 没有交集表的多对多关系?
- drupal-8 - DDEV 似乎没有安装drupal(以前工作过)
- python - 如何使用 Selenium Webdriver 在 Chrome 中关闭下载弹出窗口?
- php - 通过两个字段查询以使用 PHP 在 Firebase 中登录
- javascript - React-Webcam:我该如何解决“对象可能是‘空’。” 和“类型'null'不能分配给类型'string | undefined'。”?