繁体   English   中英

是否有使用yii2交叉连接的正确方法?

[英]Is there a proper way to cross join using yii2?

我正在查询activedataprovider,将其用于搜索目的。 我需要使用交叉联接。 我使用了joinWith,但是它抱怨仓库模型与产品没有关系。 这是产品。 因为这是交叉联接,所以在这附近有什么工作可以避免触发关系吗?

其他说明:在基于仓库的原始模型中,诸如product_id,product.category等某些属性不存在。 如果我仅添加公共属性/属性变量还是需要变通解决方案,它会即时运行吗?

public function search($params)
    {               
        $query = Warehouse::find()->joinWith('product')
                ->select(['product_id' => 'product.id','warehouse.warehouse', 'product.category', 'product.product', 'min_stock' => 'coalesce(critical.min_stock, -1)'])
                ->leftJoin('critical', 'critical.product_id = product.id AND critical.warehouse_id = warehouse.id')
                ->where(['warehouse.id' => $this->_id]);

        $this->load($params);

        $dataProvider = new ActiveDataProvider([
            'query' => $query,
        ]);        

        if (!$this->validate()) {
            // uncomment the following line if you do not want to return any records when validation fails
            // $query->where('0=1');
            return $dataProvider;
        }

        $query->andFilterWhere(['category' => $this->category]);
        $query->andFilterWhere(['like', 'product', $this->product]);        

        return $dataProvider;
    }

对于所有难以(或不可能)使用yii2 activeRecord或activeQuery功能构建的查询,可以使用findBySql

$sql = "select 
          product.id as id
          , warehouse.warehouse as warehouse 
          , product.category as category
          , product.product as product
          , coalesce(critical.min_stock, -1) as min_stock 
          from Warehouse 
          cross join product  
          left join critical on ritical.product_id = product.id AND critical.warehouse_id = warehouse.id
          where warehouse.id' = " . $this->_id  

 $model =  Warehouse::findBySql($sql );

将查询记录获取为数组,因此您无需定义关系

public function search($params)
    {               
        $query = Warehouse::find()->joinWith('product')
                ->select(['product_id' => 'product.id','warehouse.warehouse', 'product.category', 'product.product', 'min_stock' => 'coalesce(critical.min_stock, -1)'])
                ->leftJoin('critical', 'critical.product_id = product.id AND critical.warehouse_id = warehouse.id')
                ->where(['warehouse.id' => $this->_id]);

        $query = Warehouse::find()
                ->select('product.id as id,warehouse.warehouse as warehouse, product.category as category, product.product as product, coalesce(critical.min_stock, -1) as min_stock ')
                ->leftJoin('product', 'warehouse.product_id = product.id')
                ->leftJoin('critical', 'critical.product_id = product.id')
                ->where(['warehouse.id' => $this->_id]);
                ->andWhere('critical.warehouse_id = warehouse.id')
                ->asArray();

        $this->load($params);

        $dataProvider = new ActiveDataProvider([
            'query' => $query,
        ]);        

        if (!$this->validate()) {
            // uncomment the following line if you do not want to return any records when validation fails
            // $query->where('0=1');
            return $dataProvider;
        }

        $query->andFilterWhere(['category' => $this->category]);
        $query->andFilterWhere(['like', 'product', $this->product]);        

        return $dataProvider;
    }

现在,您将获得记录作为数组而不是对象。

第二种方法是,使用hasOne()hasMany()在模型中定义仓库与产品之间的关系

-> joinWith('product',true,'交叉连接')

public function getProduct()
{
    return $this->hasOne(Product::className(), []);
}

暂无
暂无

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

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