有没有一种正确的方法来使用yii2进行交叉连接?

时间:2017-07-27 15:00:10

标签: php 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;
    }

3 个答案:

答案 0 :(得分:1)

对于使用yii2 activeRecord或activeQuery functionalites构建困难(或不可能)的所有查询,您可以使用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 );

答案 1 :(得分:0)

将您的查询记录作为数组获取,这样您就不需要定义关系

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()

在模型中定义仓库与产品之间的关系

答案 2 :(得分:-1)

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

    mailVC.delegate = self