2017-08-17 155 views
0

我對mysql的知識是非常基本的,現在我正面臨着一個「複雜」(對我來說)查詢,其中我卡住了,所以如果有人可以給我一些提示, 。Yii2:從hasMany關係中選擇最後一條記錄

我有三個表:

訂單

id | name | comments | ... 

OrderLines

id | name | sDate | eDate | comments | ... 

OrderLinesStats

id | lineID | date | status | ... 

OrderLinesStats每天都通過cron作業進行更新,並獲取具有實際日期,狀態和其他字段的新記錄,因此最高的id是實際數據。

林試圖讓去年的統計,在yii2關係一行如下:

在OrdersLines模型:

public function getLastOrdersLinesStats() 
{ 
    return $this->hasMany(OrdersLinesStats::className(), ['lineID' => 'id']) 
     ->orderBy(['id'=>SORT_DESC]) 
     ->groupBy('lineID'); 
} 

OrdersModel:

public function getOrdersLines() 
    { 
     return $this 
      ->hasMany(OrdersLines::className(), ['orderID' => 'id']) 
      ->orderBy(['typeID' => SORT_ASC, 'name' => SORT_ASC]) 
      ->with(['lastOrdersLinesStats']); 
    } 

但是,當我調試查詢看起來像這樣:

SELECT * FROM `ordersLinesStats` WHERE `lineID` IN (1873, 1872, 1884, 1883, 1870, 1874, 1876, 1880, 1871, 1877, 1881, 1882, 1885, 1886, 1869, 1875, 1878) GROUP BY `lineID` ORDER BY `id` DESC 

並沒有給我每條線的最後統計記錄......事實上,它給了我最古老的一個。似乎我錯過了一些東西,但我無法找到它。

再次感謝

回答

2

在OrdersModel添加getLastOrderLineStat()方法,通過()結用途:

public function getLastOrderLineStat() 
{ 
    return $this->hasOne(OrdersLinesStats::className(), ['lineID' => 'id']) 
     ->orderBy(['id'=>SORT_DESC]) 
     ->groupBy('lineID') 
     ->via('ordersLines'); 
} 

如果$模型是一個OrdersModel例如,您可以使用獲得最後的統計一行:

$model->lastOrderLineStat 
+0

謝謝你,但與相同的查詢此結束。似乎我必須做一個子查詢,因爲這個直接運行到db:SELECT * FROM(SELECT * FROM'ordersLinesStats' WHERE'lineID' IN(1957,1954,2035,1956,1955,1958)ORDER BY'ordersLinesStats' .'id' DESC)AS LastStatsTable GROUP BY'lineID';用activequery做這件事的機會?再次感謝 – farrusete

+0

我在[link](https://stackoverflow.com/questions/45754901/yii2-subquery-within-model-relation)上創建了一個新問題,原始問題已更改 – farrusete

1

您只需要將getLastOrdersLinesStats()更改爲如下所示:

public function getLastOrdersLinesStats() 
{ 
    return $this->hasMany(OrdersLinesStats::className(), ['lineID' => 'id']) 
     ->orderBy(['id'=>SORT_DESC]) 
     ->one(); 
} 

這基本上返回你想每個訂單的最後OrderLinesStats一行

你可以訪問此如下:

,如果你有例如 稱爲myOrder一個對象,那麼你可以訪問你想要的行作爲myOrder->lastOrderLinesStats

+0

謝謝mrateb。如果我在每一條記錄上使用這種方法,這將工作,並以db的大量查詢結束。我想通過使用 - > with(['lastOrdersLinesStats'])來進行單個查詢;並且似乎用子查詢進行是一條路。 – farrusete

0

我只是回答這是徹底的,並希望可以幫助其他人絆倒在這個頁面上。

我推薦總是包括hasOnehasMany。這樣,您可以彈出頂部記錄,或者檢索所有記錄。

/** 
* @return \yii\db\ActiveQuery 
*/ 
public function getUserPlan() 
{ 
    return $this->hasOne(UserPlan::className(), ['user_id' => 'id']) 
     ->orderBy(['id' => SORT_DESC]) 
     ->one(); 
} 

/** 
* @return \yii\db\ActiveQuery 
*/ 
public function getUserPlans() 
{ 
    return $this->hasMany(UserPlan::className(), ['user_id' => 'id']) 
     ->orderBy(['id' => SORT_DESC]) 
     ->all(); 
} 

hasMany將返回ActiveQuery對象,其中hasOne則會自動返回只是一個ActiveQuery對象的陣列。

你(在UserController中例如在用戶模式)使用它們像這樣:

$model = $this->findOne($id); 

$model = User::findOne($id); 

$model = User::find()->where(['id' => $id])->one(); 

然後抓住像這樣的關係:

$plan = $model->userPlan 

$plans = $model->userPlans 

對於userPlan:

$planId = $plan->id; 

處理userPlans:

foreach($plans as $plan) { 
    $plan->id; 
} 
相關問題