当前位置:  开发笔记 > 编程语言 > 正文

Yii2 - 在多个条件下左连接

如何解决《Yii2-在多个条件下左连接》经验,为你挑选了2个好方法。

我有三张表,关系如下,

  ------- 1        0..* ------------
 |Product|-------------|Availability|
  -------               ------------
    1 |
      |
    1 |
  --------
 |MetaData|
  --------

我的原始SQL看起来像这样

SELECT p.ID FROM product p 
LEFT JOIN availability a ON a.productID=p.ID 
          AND a.start>=DATE_ADD(DATE(now()), INTERVAL 7 DAY)
LEFT JOIN meta_data m ON m.ID=p.meta_dataID
WHERE a.ID IS NULL
AND m.published_state=1;

也就是说,发现每Product一个MetaData.published_state等于1并没有Availability使得Availability.start从超过7天now().

我正在尝试使用以下ActiveRecord方法完成相同的使用方法,

$products = Product::find()
            ->joinWith('metaData')
            ->joinWith('availability')
            ->onCondition(['>=', 'availability.start', strtotime('+7 days')])
            ->where(['is', 'availability.ID', NULL])
            ->andWhere(['=', 'meta_data.published_state', 1])
            ->all();

但是,这没有结果.使用Connection::createCommand()运行原始SQL返回我期望的行,所以有与数据没有问题.

我怀疑这个问题是由join条件和where条件"流血" 引起的; 加入和应用于加入或在哪里而不是分开.

如何输出正在运行的实际sql查询?这是从控制台控制器调用的动作.

如何更改我的代码以返回所需的代码Products



1> Yerke..:

我相信这个是更好的解决方案.而不是像leftJoin你一样使用Raw查询应该补充你的joinWith关系andOnCondition(在条件加入你的连接语句时需要添加).

$products = Product::find()
    ->joinWith(['metaData' => function (ActiveQuery $query) {
        return $query
            ->andWhere(['=', 'meta_data.published_state', 1]);
    }])
    ->joinWith(['availability' => function (ActiveQuery $query) {
        return $query
            ->andOnCondition(['>=', 'availability.start', strtotime('+7 days')])
            ->andWhere(['IS', 'availability.ID', NULL]);
    }])
    ->all();

另外,当你where在关系中写条款时它看起来更干净.它的工作方式与在外面编写相同(如果我没有错),但在重构查询时,您可以轻松删除整个关系而不会忘记外部的关系条件.



2> Ishan Shah..:

只需使用以下条件.

$query = Product::find()
 -> leftJoin('availability', 'availability.productID=product.ID  AND a.start>=DATE_ADD(DATE(now()), INTERVAL 7 DAY)')
 ->leftJoin('meta_data', 'meta_data.ID=product.meta_dataID')
 ->where(['is', 'availability.ID', NULL])
 ->andWhere(['=', 'meta_data.published_state', 1])
 ->all();

推荐阅读
N个小灰流_701
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有