繁体   English   中英

Yii2-每天查询到ActiveRecord的次数

[英]Yii2 - Query count per day to ActiveRecord

我具有以下表结构,并使用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        |
------------------------------------       

因此,对于给定的Supplier没有预订的日期,应输入0 ,就像这样

------------------------------------
| 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;
    }

}

这给了我一个供每个供应商使用的数组,其计数存储在适当的当日索引下,但感觉效率很低。

我可以重构该代码以更少的数据库调用和更少的“脚手架”代码返回所需的数据吗?

这可能是您选择的第一个问题

    $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();

通过这种方式,您应该获得供应商ID(和order_day)行,从而避免了供应商上的foreach

为了获取$ results-> num_bookings和order_day中的数据,您需要添加

 public $num_bookings; 
 public $order_day; 

在您的OrderLine模型中

我希望这是您要寻找的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM