我显示从今天起3个月的订单。如果今天是2015年7月17日,我将显示2015年4月17日至2015年7月17日的数据。我的问题是我必须按周显示这些数据。在3个月内有12个星期。我必须显示所有12周的订单平均价格。
现在,在我的查询中,我显示了此期间的所有订单。但我不必显示所有订单的average_prices,必须显示12周的12个平均价格。怎么做?
<?php
public function average_price_by_week() {
$date = new DateTime("now");
$date->modify('-3 month');
$current =$date->format('Y-m-d');
$this->db->select('DATE_FORMAT(DATE_SUB(ordersheader.createdDate, INTERVAL DAYOFWEEK(ordersheader.createdDate)-2 DAY), "%Y-%m-%d") AS "interval"',FALSE);
$this->db->select_avg('unitPrice');
$this->db->from('orderitems');
$this->db->join('ordersheader', 'ordersheader.idOrder=
orderitems.idOrder');
$this->db->where('ordersheader.createdDate > ',$current);
$this->db->order_by('interval');
$this->db->group_by('interval');
$query=$this->db->get();
return $query->result_array();
我的表ordersheader
具有结构:
idOrder
(主要关键字),idCustomer
,createdDate
,orderDueDate
我的表orderitems
具有结构:
id
(主要关键字),idOrder
,itemNumber,
wrappingType ,
尺寸,
数量,
unitPrice ,
收入
一个idOrder可以有很多订单。
编辑:我必须在图表中显示这些数据。在我的控制器中我有: 如何显示来自查询而不是数组$ firm的周和间隔的平均价格从上面的数组获取值?
<?php
public function column_chart() {
$size = $this->uri->segment(3);
$interval = $this->uri->segment(4);
$firms = $this->Receivedorders_model->average_price_by_week($size,$interval);
$new_result_array=[];
$average_prices=[];
foreach($firms as $row){
if(!isset($new_result_array[date('W',strtotime($row['interval']))])){
$new_result_array[date('W',strtotime($row['interval']))]=[];
$new_result_array[date('W',strtotime($row['interval']))]['weekly_order_total']=0;
$new_result_array[date('W',strtotime($row['interval']))]['orders']=[];
}
$new_result_array[date('W',strtotime($row['interval']))]['weekly_order_total']+=$row['unitPrice'];
$new_result_array[date('W',strtotime($row['interval']))]['orders'][]=$row;
}
print_r($new_result_array);
foreach($new_result_array as $week=>$orders){
$average_prices[$week]=$orders['weekly_order_total']/count($orders['orders']);
}
print_r($average_prices);
/* How to show average price by week and interval from query in the following array -instead of $firms to take values from the above array */
$p = array();
foreach ($firms as $key => $firm) {
$p[$key] = array('c' => array(array(
'v' => $firm['interval'],
),
array(
'v' => round($firm['unitPrice'],2),
)));
}
echo json_encode(array(
'cols' => array(
array('id' => 'name', 'label' => lang("customer"), 'type' => 'string'),
array('id' => 'incomes', 'label' => lang("chart_average_price"), 'type' => 'number'),
),
'rows' => $p
));
}
答案 0 :(得分:3)
要在PHP中执行整个过程,请更改您的选择并移除select_avg
并正常选择unitPrice
。
$new_result_array=[];
$average_prices=[];
foreach($result_array as $row){
//Initialize the index's if they dont exist
if(!isset($new_result_array[date('W',strtotime($row['createdDate']))]){
$new_result_array[date('W',strtotime($row['createdDate'])]=[];
$new_result_array[date('W',strtotime($row['createdDate'])]['weekly_order_total']=0;
$new_result_array[date('W',strtotime($row['createdDate'])]['orders']=[];
}
//Edited to wrap $row['createdDate'] in strtotime() as all dates are returning week 1
$new_result_array[date('W',strtotime($row['createdDate']))]['weekly_order_total']+=$row['unitPrice'];
$new_result_array[date('W',strtotime($row['createdDate']))]['orders'][]=$row;
}
print_r($new_result_array);
foreach($new_result_array as $week=>$orders){
$average_prices[$week]=$orders['weekly_order_total']/count($orders['orders']);
}
print_r($average_prices);
W
作为日期格式将为您提供weeek的编号(即1-52)。如果您需要显示每周期间的开始和结束日期,则需要解析该数字。有关详细信息,请参阅此问题(可能还有其他问题)
答案 1 :(得分:0)
不是可移植的解决方案(它使用MySQL功能;其他RDBM具有相似的功能但名称不同),但您可以按WEEKOFYEAR()
对数据进行分组。唯一需要注意的是,如果你在1月份这样做,你会得到例如周#48,#49,#50,#51,#52,#1,#2,#3,你需要对它们进行排序就像那样(即52在1之前)。< / p>
所以你可以提取
MIN(ordersheader.createdDate) AS firstOrderDate,
WEEKOFYEAR(ordersheader.createdDate) AS weekNumber,
然后按weekNumber
分组,但按firstOrderDate
排序(不显示)。
如果您在间隔中缺少数据,则可能是另一个问题。
也许更高层次的方法是:
您可以在查询中添加缺少的数据,但这很棘手。假设您有一个像
这样的结果数组,那么PHP的一种更平易近人的方式就是这样$results = array(
0 => array(
'createdDate' => '2015-07-17',
'value' => 2500, // This is the DAY AVERAGE for that day
...
),
然后你可以做类似的事情,
$weeks = array();
foreach ($results as $row) {
$weekNumber = date('W', $row['createdDate']);
if (array_key_exists($weekNumber, $weeks)) {
$week = $weeks[$weekNumber];
} else {
$week = array( 'value' => 0, 'count' => 0 );
}
$week['count'] ++;
$week['value'] += $row['value'];
}
// Now get the average
foreach ($weeks as $n => $week) {
$weeks[$n]['value'] /= $weeks[$n]['count'];
}
// Now we have $weeks, with "holes" for periods with no data:
/*
$weeks = array(
51 => [ 'value' => 172.371, 'count' => 3 ],
2 => [ 'value' => 211.952, 'count' => 7 ],
...
);
*/
// To fill holes, we first need to choose how to do that (see above).
注意:上述方法中存在(可能接受的)概念错误,其中平均日均值。假设我们有:
Day Price
17 1000
17 1000
17 1000
18 2000
日平均值为:17 = 1000,18 = 2000.如果两天都在同一周,则1000和2000的平均值将给出一周的平均值1500.然而在那一周我们有四个订单,并且那些的平均值实际上是1250。
当您说“周平均值”时,存在歧义,因为不清楚它是每天的平均价格,还是整个期间所有订单的平均价格。
如果您想要第二种平均值,则需要按周编号分组,这是我上面的初步提案。