简体   繁体   English

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

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

I'm doing a query for activedataprovider, which I'm going to use for the purpose of search. 我正在查询activedataprovider,将其用于搜索目的。 I need to use cross join. 我需要使用交叉联接。 I used joinWith, but it complains about warehouse model not having relation with product. 我使用了joinWith,但是它抱怨仓库模型与产品没有关系。 it was calling product. 这是产品。 Are there any work around here so that it won't trigger the relation, since it's a cross join? 因为这是交叉联接,所以在这附近有什么工作可以避免触发关系吗?

Other notes: Certain attributes like product_id, product.category, etc doesn't exist on the original model which is based on warehouse. 其他说明:在基于仓库的原始模型中,诸如product_id,product.category等某些属性不存在。 Will it work on the fly if I just add public property/attribute variables or do I need a work around? 如果我仅添加公共属性/属性变量还是需要变通解决方案,它会即时运行吗?

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;
    }

For all the query that are difficult (or impossibile) to build using yii2 activeRecord or activeQuery functionalites you can use findBySql 对于所有难以(或不可能)使用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 );

Get Your Query record as array so you don't require to define relationship 将查询记录获取为数组,因此您无需定义关系

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;
    }

Now you will get record as Array not as object. 现在,您将获得记录作为数组而不是对象。

Second way is, Define relation between Warehouse and Product in model using hasOne() or hasMany() 第二种方法是,使用hasOne()hasMany()在模型中定义仓库与产品之间的关系

->joinWith('product', true,'cross join') -> 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