2016-05-17 96 views
0

我有以下MySQL查詢,我需要在yii2使用 -MySQL查詢中的ActiveRecord在yii2

select tsell.district,tsell.totalsale as sell,coalesce(tcollection.collection,0) as collection from(SELECT district, coalesce(sell.sale,0) as totalsale FROM `districts` left join (SELECT parties_district, billdate,sum(billamount) as sale FROM `bills` left join parties on bills.bills_partyname = parties.parties_partyname group by parties_district) as sell on sell.parties_district = districts.district) as tsell left join (SELECT parties_district,payment_date,COALESCE(sum(payment_amount),0) as collection FROM `payment` left join parties on payment.payment_partyname = parties.parties_partyname group by parties_district) as tcollection on tsell.district = tcollection.parties_district 

我的搜索模式是

<?php 

namespace frontend\modules\districtreport\models; 

use Yii; 
use yii\base\Model; 
use yii\data\ActiveDataProvider; 
use frontend\modules\districtreport\models\Parties; 
use frontend\modules\districtreport\models\Bills; 
use frontend\modules\districtreport\models\Payment; 
use yii\db\Query; 
use yii\db\Command; 
$query = \Yii::$app->db; 
/** 
* PartiesSearch represents the model behind the search form about `frontend\modules\districtreport\models\Parties`. 
*/ 
class PartiesSearch extends Parties 
{ 
    public $bills; 
    public $district; 
    public $sale; 
    public $sell; 
    public $collection; 
    /** 
    * @inheritdoc 
    */ 
    public function rules() 
    { 
     return [ 
      [['party_id'], 'integer'], 
      [['parties_partyname', 'address', 'parties_district', 'name_manager', 'transport', 'dlno', 'instruction', 'con', 'district','sale','sell','collection'], 'safe'], 
     ]; 
    } 

    /** 
    * @inheritdoc 
    */ 
    public function scenarios() 
    { 
     // bypass scenarios() implementation in the parent class 
     return Model::scenarios(); 
    } 

    /** 
    * Creates data provider instance with search query applied 
    * 
    * @param array $params 
    * 
    * @return ActiveDataProvider 
    */ 
    public function search($params) 
    { 

     $sql = 'select tsell.district,tsell.totalsale as sell,coalesce(tcollection.collection,0) as collection from(SELECT district, coalesce(sell.sale,0) as totalsale FROM `districts` left join (SELECT parties_district, billdate,sum(billamount) as sale FROM `bills` left join parties on bills.bills_partyname = parties.parties_partyname group by parties_district) as sell on sell.parties_district = districts.district) as tsell left join (SELECT parties_district,payment_date,COALESCE(sum(payment_amount),0) as collection FROM `payment` left join parties on payment.payment_partyname = parties.parties_partyname group by parties_district) as tcollection on tsell.district = tcollection.parties_district'; 
     $query = Parties::findBySql($sql); 

     // add conditions that should always apply here 

     $dataProvider = new ActiveDataProvider([ 
      'query' => $query, 
      //'sort'=> ['defaultOrder' => ['district'=>SORT_DESC]] 
     ]); 

     $dataProvider->sort->attributes['sell'] = [ 
     // The tables are the ones our relation are configured to 
     // in my case they are prefixed with "tbl_" 
     'asc' => ['tsell.sell' => SORT_ASC], 
     'desc' => ['tsell.sell' => SORT_DESC], 
     ]; 

     $dataProvider->sort->attributes['collection'] = [ 
     // The tables are the ones our relation are configured to 
     // in my case they are prefixed with "tbl_" 
     'asc' => ['collection' => SORT_ASC], 
     'desc' => ['collection' => SORT_DESC], 
     ]; 
     $dataProvider->sort->attributes['district'] = [ 
     // The tables are the ones our relation are configured to 
     // in my case they are prefixed with "tbl_" 
     'asc' => ['tsell.district' => SORT_ASC], 
     'desc' => ['tsell.district' => SORT_DESC], 
     ]; 


     $this->load($params); 

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

     // grid filtering conditions 
     $query->andFilterWhere([ 
      'party_id' => $this->party_id, 
     ]); 

     $query->andFilterWhere(['like', 'parties_partyname', $this->parties_partyname]) 
      ->andFilterWhere(['like', 'address', $this->address]) 
      ->andFilterWhere(['like', 'parties_district', $this->parties_district]) 
      ->andFilterWhere(['like', 'name_manager', $this->name_manager]) 
      ->andFilterWhere(['like', 'transport', $this->transport]) 
      ->andFilterWhere(['like', 'dlno', $this->dlno]) 
      ->andFilterWhere(['like', 'instruction', $this->instruction]) 
      ->andFilterWhere(['like', 'con', $this->con]) 
      ->andFilterWhere(['like', 'sell', $this->sell]) 
      ->andFilterWhere(['like', 'collection', $this->collection]) 
      ->andFilterWhere(['like', 'district', $this->district]); 

     return $dataProvider; 
    } 
} 

但問題是,我無法進行排序或過濾列。所以我想用activerecord來運行查詢而不是findbysql。請幫助我在activerecord中構建此查詢。

我的index.php文件看起來像 -

<?php 

use yii\helpers\Html; 
use yii\grid\GridView; 
//use kartik\widgets\DatePicker; 
use kartik\daterange\DateRangePicker; 
use kartik\form\ActiveForm; 
use dosamigos\datepicker\DatePicker; 

/* @var $this yii\web\View */ 
/* @var $searchModel frontend\modules\districtreport\models\PartiesSearch */ 
/* @var $dataProvider yii\data\ActiveDataProvider */ 

$this->title = 'Parties'; 
$this->params['breadcrumbs'][] = $this->title; 
?> 
<div class="parties-index"> 

    <h1><?= Html::encode($this->title) ?></h1> 
    <?php // echo $this->render('_search', ['model' => $searchModel]); ?> 

<!--  <p> 
     <?= Html::a('Create Parties', ['create'], ['class' => 'btn btn-success']) ?> 
    </p> --> 
    <!-- <div class="custom-filter"> 

    Date range: 
    <input name="start" /> 
    <input name="end" /> 

    </div> --> 


     <?= GridView::widget([ 
     'dataProvider' => $dataProvider, 
     'filterModel' => $searchModel, 
     'columns' => [ 
      ['class' => 'yii\grid\SerialColumn'], 


      'district',   
      'sell', 
      'collection', 


      //['class' => 'yii\grid\ActionColumn'], 
     ], 
    ]); ?> 
</div> 

這裏是我的PartiesController.php

<?php 

namespace frontend\modules\districtreport\controllers; 

use Yii; 
use frontend\modules\districtreport\models\Parties; 
use frontend\modules\districtreport\models\PartiesSearch; 
use yii\web\Controller; 
use yii\web\NotFoundHttpException; 
use yii\filters\VerbFilter; 

/** 
* PartiesController implements the CRUD actions for Parties model. 
*/ 
class PartiesController extends Controller 
{ 
    /** 
    * @inheritdoc 
    */ 
    public function behaviors() 
    { 
     return [ 
      'verbs' => [ 
       'class' => VerbFilter::className(), 
       'actions' => [ 
        'delete' => ['POST'], 
       ], 
      ], 
     ]; 
    } 

    /** 
    * Lists all Parties models. 
    * @return mixed 
    */ 
    public function actionIndex() 
    { 
     $searchModel = new PartiesSearch(); 
     $dataProvider = $searchModel->search(Yii::$app->request->queryParams); 

     return $this->render('index', [ 
      'searchModel' => $searchModel, 
      'dataProvider' => $dataProvider, 
     ]); 
    } 

    /** 
    * Displays a single Parties model. 
    * @param integer $id 
    * @return mixed 
    */ 
    public function actionView($id) 
    { 
     return $this->render('view', [ 
      'model' => $this->findModel($id), 
     ]); 
    } 

    /** 
    * Creates a new Parties model. 
    * If creation is successful, the browser will be redirected to the 'view' page. 
    * @return mixed 
    */ 
    public function actionCreate() 
    { 
     $model = new Parties(); 

     if ($model->load(Yii::$app->request->post()) && $model->save()) { 
      return $this->redirect(['view', 'id' => $model->party_id]); 
     } else { 
      return $this->render('create', [ 
       'model' => $model, 
      ]); 
     } 
    } 

    /** 
    * Updates an existing Parties model. 
    * If update is successful, the browser will be redirected to the 'view' page. 
    * @param integer $id 
    * @return mixed 
    */ 
    public function actionUpdate($id) 
    { 
     $model = $this->findModel($id); 

     if ($model->load(Yii::$app->request->post()) && $model->save()) { 
      return $this->redirect(['view', 'id' => $model->party_id]); 
     } else { 
      return $this->render('update', [ 
       'model' => $model, 
      ]); 
     } 
    } 

    /** 
    * Deletes an existing Parties model. 
    * If deletion is successful, the browser will be redirected to the 'index' page. 
    * @param integer $id 
    * @return mixed 
    */ 
    public function actionDelete($id) 
    { 
     $this->findModel($id)->delete(); 

     return $this->redirect(['index']); 
    } 

    /** 
    * Finds the Parties model based on its primary key value. 
    * If the model is not found, a 404 HTTP exception will be thrown. 
    * @param integer $id 
    * @return Parties the loaded model 
    * @throws NotFoundHttpException if the model cannot be found 
    */ 
    protected function findModel($id) 
    { 
     if (($model = Parties::findOne($id)) !== null) { 
      return $model; 
     } else { 
      throw new NotFoundHttpException('The requested page does not exist.'); 
     } 
    } 
} 
+0

同比表示ai想要使用activeRecord。 。 activeRecord的意思是基於表你使用臨時表..在這種情況下,findBySql似乎是正確的chioce ...最後,排序和過濾器與dataProvider獨立相關,如果你使用find()或findBySql .. – scaisEdge

+0

我想要的是按地區,銷售和收集過濾和分類數據。 – Tanmay

+0

你有沒有嘗試過我的答案排序?工作? ..不工作? ..錯誤? – scaisEdge

回答

0

PLS有look

$dataProvider = new SqlDataProvider([ 
    'sql' => 'SELECT Name, Title, COUNT(ArticleTags.ID) AS TagCount ' . 
      'FROM Authors ' . 
      'INNER JOIN Articles ON (Authors.ID = Articles.AuthorID) ' . 
      'INNER JOIN ArticleTags ON (Articles.ID = ArticleTags.ID) ' . 
      'WHERE Name=:author' . 
      'GROUP BY ArticleID', 
    'params' => [':author' => 'Arno Slatius'], 
]); 
0

查詢是否缺少區別名

select 
     tsell.district as district, 
     tsell.totalsale as sell, 
     coalesce(tcollection.collection,0) as collection 
     from 
      (SELECT 
       district, 
       coalesce(sell.sale,0) as totalsale 
      FROM `districts` 
      left join 
       (SELECT 
        parties_district, 
        billdate, 
        sum(billamount) as sale 
       FROM `bills` 
       left join parties on bills.bills_partyname = parties.parties_partyname 
       group by parties_district) as sell 
      on sell.parties_district = districts.district) as tsell 
     left join 
      (SELECT 
       parties_district, 
       payment_date, 
       COALESCE(sum(payment_amount),0) as collection 
      FROM `payment` 
      left join parties on payment.payment_partyname = parties.parties_partyname 
      group by parties_district) as tcollection 
       on tsell.district = tcollection.parties_district 

對於那種我建議你這個符號

$dataProvider->setSort([ 
      'attributes' => [ 
       'sell' => [ 
        'asc' => ['tsell.sell' => SORT_ASC], 
        'desc' => ['tsell.sell' => SORT_DESC], 
        'label' => 'Sell' 
       ], 
       'collection' => [ 
        'asc' => ['collection' => SORT_ASC], 
        'desc' => ['collection' => SORT_DESC],  
        'label' => 'Collection' 
       ]  
       'district' => [ 
        'asc' => ['tsell.district' => SORT_ASC], 
        'desc' => ['tsell.district' => SORT_DESC], 
        'label' => 'District' 
       ]        
      ] 
     ]); 

要確保你有隻在一個模型類聲明瓦爾$bills, $district, $sale, $sell, $collection。 如果使用這些瓦爾幾個擴展searchModel那麼只有在模型 聲明,否則申報只在searhModel ..

兩個相同的變種一個永遠不要聲明通過模型或modelSearch功能使用時覆蓋他人和錯配..

+0

我的問題是我怎麼可以在ActiveDataProvider中編寫這個查詢,如''query'=> Articles :: find() - > with('author') - > where(['Name'=>'Arno Slatius']), ....我也無法對數據進行排序或過濾 – Tanmay

+0

我已經用新建議更新了答案 – scaisEdge

+0

我只在締約方模型中添加了這些變量,並將它從締約方模型中刪除。但仍然無法排序或過濾。請幫忙。請告訴如何過濾它。因爲我在其中添加了kartik expandrow。過濾器列正在將區域傳遞到第二級,但不是過濾。請幫忙。 – Tanmay