Yii2模型 - 活动记录joinWith +和日期选择

时间:2017-02-05 17:31:34

标签: php sql yii2 yii2-model

我喜欢在两个相关的Yii2 models上选择特定的相关数据。两个模型都处于1:n关系。这种关系工作正常!

订单型号:

  • @property integer $ id

订单模型关系定义:

/**
 * @return \yii\db\ActiveQuery
 */
public function getTimeCaptures()
{
    return $this->hasMany(TimeCapture::className(), ['orderId' => 'id']);
}

timeCapture 型号:

  • @property integer $ id
  • @property integer $ orderId
  • @property string $ date(MySQL-DB中的Datetime

我希望在特定日期之间获得与orders相关的所有timeCaptures。以下声明将给我所有timeCaptures。似乎andWhere条款无效!

/**
 * Build query
 */
$orders = Order::find()
    ->joinWith('timeCaptures')
    ->andWhere([
        '>=',
        'timeCapture.date',
        $startDateSearch->format('Y-m-d H:i:s')
    ])
    ->andWhere([
        '<=',
        'timeCapture.date',
        $endDateSearch->format('Y-m-d H:i:s')
    ])->all();

这是$orders->createCommand()->getRawSql()的原始SQL输出:

SELECT `order`.*
    FROM `order`
LEFT JOIN `timeCapture` ON `order`.`id` = `timeCapture`.`orderId`
    WHERE (`timeCapture`.`date` >= '2017-02-01 00:00:00')
    AND (`timeCapture`.`date` <= '2017-02-28 00:00:00')

请提供使用Yii2 active records的答案。提前谢谢。

2 个答案:

答案 0 :(得分:4)

如果我找对你,这就是你要找的东西:

$startDateSearch = new DateTime('2017-02-10');
$endDateSearch   = new DateTime('2017-02-17');
$orders = Order::find()->with([
    'timeCaptures' => function (\yii\db\ActiveQuery $query) use($startDateSearch, $endDateSearch) {
        $query
            ->andWhere([
                '>=',
                'timeCapture.date',
                $startDateSearch->format('Y-m-d H:i:s')
            ])
            ->andWhere([
                '<=',
                'timeCapture.date',
                $endDateSearch->format('Y-m-d H:i:s')
            ]);
    },
])->all();
var_dump($orders);

对于迟到的回答感到抱歉

答案 1 :(得分:1)

你试过这个吗?

/**
 * Build query
 */
$orders = Order::find()
    ->joinWith('timeCaptures')
    ->with('timeCaptures') // this is what you should add
    ->andWhere([
        '>=',
        'timeCapture.date',
        $startDateSearch->format('Y-m-d H:i:s')
    ])
    ->andWhere([
        '<=',
        'timeCapture.date',
        $endDateSearch->format('Y-m-d H:i:s')
    ])->all();

我们的想法是,使用joinWith创建一个允许您对两个表进行过滤的连接,这正是您所做的。但您也可以使用预先加载http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#lazy-eager-loading来获取相同查询中的相关模型。我相信这实际上可能会创建您正在寻找的确切查询。它应该创建

SELECT `order`.*, `timeCapture`.*
    FROM `order`
LEFT JOIN `timeCapture` ON `order`.`id` = `timeCapture`.`orderId`
    WHERE (`timeCapture`.`date` >= '2017-02-01 00:00:00')
    AND (`timeCapture`.`date` <= '2017-02-28 00:00:00')

同时在退役订单和timeCapture记录之间建立正确的关系,以便您能够使用

访问它们
$order->timeCaptures