Yii2 - 每天向ActiveRecord

时间:2016-01-04 10:11:34

标签: php mysql yii2

我有以下表结构并使用Yii2 ActiveRecord方法我想提取供应商下周每天的预订数量(OrderLine)(也需要0个条目) )。因此,根据供应商的不同,每个供应商每天获得一行的方式为num_bookings或可能为0

 /--------------------\                  /------------\
 | OrderLine          |------------------|Availability| 
 |--------------------| 0..n           1 |------------|
 |ID {PK}             |                  |ID {PK}     |
 |availabilityID {FK} |                  |start       |
 |line_status         |                  \------------/
 |supplierID   {FK}   |
 \--------------------/
          | 1
          |
          |
          | 1
     /----------\
     | Supplier |
     |----------|
     |ID {PK}   |
     \----------/

使用DAO直接查询数据库,使用以下SQL为我提供了(几乎)所需的结果,

select count(ol.ID) as num_bookings, 
       day(from_unixtime(a.start)) as order_day,
       ol.supplierID
from order_line ol left join 
availability a on ol.availabilityID = a.ID
where ol.line_status = "booked"
and a.start >= 1451952000   //magic number for midnight today
and a.start <= 1452556800   //magic number for seven days from now
group by order_day, ol.supplierID;

的内容
------------------------------------
| num_bookings|order_day|supplierID|
------------------------------------
| 1           | 5       | 3        |
| 2           | 5       | 7        |
| 1           | 6       | 7        |
| 1           | 7       | 7        |
------------------------------------       

因此,在给定的0没有预订的日子里应该有Supplier的条目,例如

------------------------------------
| num_bookings|order_day|supplierID|
------------------------------------
| 1           | 5       | 3        |
| 0           | 6       | 3        |
| 0           | 7       | 3        |
| 2           | 5       | 7        |
| 1           | 6       | 7        |
| 1           | 7       | 7        |
------------------------------------  
[days 8+ omitted for brevity...]

我有一些php / Yii代码,它们[最终]会给我类似的东西,但涉及多个查询和数据库连接,如下所示,

$suppliers = Supplier::find()->all(); // get all suppliers

$start = strtotime('tomorrow');
$end = strtotime('+7 days', $start);  // init times

// create empty assoc array with key for each of next 7 days
$booking_counts[date('D j', $start)] = 0;
for ($i=1; $i<7; ++$i) {
   $next = strtotime('+'.$i." days", $start);
   $booking_counts[date('D j', $next)] = 0;
}

foreach ($suppliers as $supplier) {
     $bookings = OrderLine::find()
                    ->joinWith('availability')
                    ->where(['order_line.supplierID' => $supplier->ID])
                    ->andWhere(['>=', 'availability.start', $start])
                    ->andWhere(['<=', 'availability.start', $end])
                    ->andWhere(['order_line.line_status' => 'booked'])
                    ->orderBy(['availability.start' => SORT_ASC])
                    ->all();

    $booking_count = $booking_counts;
    foreach ($bookings as $booking) {
        $booking_count[date('D j', $booking->availability->start)] += 1;
    }

}

这为每个供应商提供了一个数组,其中的计数存储在相应日期的索引之下,但效率非常低。

我是否可以重构此代码以使用较少的数据库调用和较少的“scaffold”代码返回所需的数据?

1 个答案:

答案 0 :(得分:1)

这可能是你的第一选择

的遗留问题
    $results = OrderLine::find()
        ->select('count(order_line.ID) as num_bookings, day(from_unixtime(availability.start)) as order_day', order_line.supplierID )
        ->from('order_line')
        ->leftjoin('availability', 'order_line.availabilityID = availability.ID')
        ->where( 'order_line.line_status = "booked"
            and a.start >= 1451952000   
            and a.start <= 1452556800')
        ->groupBy(order_day, order_line.supplierID)
        ->orderBy(['availability.start' => SORT_ASC])
        ->all();

通过这种方式,您应该获取supplierID(和order_day)的行,以避免供应商的foreach

要获取$ results-&gt; num_bookings和order_day中的数据,您需要添加

 public $num_bookings; 
 public $order_day; 
订单线模型中的

我希望这就是你要找的东西。