我有以下表结构并使用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”代码返回所需的数据?
答案 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;
订单线模型中的
我希望这就是你要找的东西。