如何使用hasOne和onCondition创建关系查询?

时间:2017-11-29 14:50:04

标签: activerecord yii2 entity-relationship yii2-model

relation query

sql

因为我有一个索引(user_id,lesson_id),我想用该索引查询。

对于图像,它不使用索引,对吗?

注意:USER_ID是INTEGER VALUE而不是FIELD。

//the following SQL it is my expecting:
//not generate by php code. just show a example for what to do.
LEFT JOIN `user_lesson_order` ON (
    //user_id is current logined 
    `user_lesson_order` . `user_id` = 29
) 
AND ( 
    `lesson_favorite` . `lesson_id` = `user_lesson_order` . `lesson_id`
)
AND ...
AND ...

//the wrong php code. it will generate a wrong sql;
public function getLessonOrder() {
    return $this->hasOne(UserLessonOrder::class, [
        UserLessonOrder::tableName() . '.user_id' => $this->user_id,
        'lesson_id' => 'lesson_id'
    ])->onCondition([
        UserLessonOrder::tableName() . '.payment_status' =>SystemCode::COMMON_PAYMENT_STATUS_YES,
        UserLessonOrder::tableName() . '.status' => SystemCode::COMMON_STATUS_ENABLE
    ]);
}
//the wrong sql:
LEFT JOIN `user_lesson_order` ON (
   //user_lesson_order.user_id = 41, this is my expect sql. 
   `lesson_favorite`.`41` = `user_lesson_order`.`user_id`

    AND `lesson_favorite`.`lesson_id` = `user_lesson_order`.`lesson_id`
) AND (
(
    `user_lesson_order`.`payment_status` = 'COMMON_PAYMENT_STATUS_YES'
) AND (
    `user_lesson_order`.`status` = 'COMMON_STATUS_ENABLE'
)
)
Unknown column 'lesson_favorite.41' in 'on clause'
fllow php代码会生成正确的sql。但它无法使用unique_key(user_id,lesson_id);

//follow code is working. but genarate a sql cant not use unique_key(user_id,lesson_id);
public function getLessonOrder() {
return $this->hasOne(UserLessonOrder::class, [
    'lesson_id' => 'lesson_id'
])->onCondition([
    UserLessonOrder::tableName() . '.user_id' => $this->user_id,
    UserLessonOrder::tableName() . '.payment_status' =>SystemCode::COMMON_PAYMENT_STATUS_YES,
    UserLessonOrder::tableName() . '.status' => SystemCode::COMMON_STATUS_ENABLE
    ]);
}


//sql generate by php code,it is working. but cant use unique_index(user_id,lesson_id);
LEFT JOIN `user_lesson_order` ON (
    `lesson_favorite` . `lesson_id` = `user_lesson_order` . `lesson_id`
) AND ( 
    //user_id is current logined 
   `user_lesson_order` . `user_id` = 29
)
AND ...
AND ...

请告诉我:

1,哪种情况将使用数据库unique_key (user_id,lesson_id)的索引;

2,如何创建这样的查询?第一个是user_id,然后是lesson_id。

//user_id is current logined
left join user_lesson_order on user_lesson_order.user_id = 29 
and lesson_favorite.lesson_id = user_lesson_order.lesson_id

2 个答案:

答案 0 :(得分:1)

public function getLessenOrder() {
    return $this->hasOne(UserLessonOrder::class, [
     // 'user_id'   => 'user_id', // is it part of the relation?
        'lesson_id' => 'lesson_id', 
    ])->onCondition([
        UserLessonOrder::tableName() . '.payment_status' => SystemCode::COMMON_PAYMENT_STATUS_YES,
        UserLessonOrder::tableName() . '.status'         => SystemCode::COMMON_PAYMENT_ENABLE, 
        UserLessonOrder::tableName() . '.user_id'        => $this->user_id,
    ])
}

这应该这样做。创建的JOIN应该使用索引。不是吗?您可以查看runtime/logs/app.log以查看生成的查询。

如果可行则唯一的区别是在$linkhasOne()的{​​{1}}参数中使用了正确的字段名称,而不是session_id。使用此参数,您只需说明哪些字段(列)应该相关 - 这里不能使用值。这可以在session已经完成的工作中完成。

答案 1 :(得分:0)

您可以使用多个字段来定义关系链接

$this->hasOne(
        UserLessonOrder::class, 
        ['lesson_id' => 'lesson', 'user_id' => 'user_id']
    )
    ->onCondition([
        'payment_status' => ...
        'status'         => ...  
    ])

在关系定义中使用任何模型属性($this->user_id)都会在大多数情况下导致问题