2017-08-17 5 views
0

mysqlに関する私の知識は非常に基本的なものであり、今私は「複雑な」クエリに直面しています。 。Yii2:hasMany関係の最後のレコードを選択

受注

id | name | comments | ... 

注文ライン

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

OrderLinesStats

は、私は3つのテーブルを持っています10

id | lineID | date | status | ... 

毎日、OrderLinesStatsはcronジョブを介して更新され、実際の日付、ステータス、およびその他のフィールドを持つ新しいレコードを取得し、最高のIDが実際のデータとなるようにします。

イム次のようにyii2中関係とその最後の統計行を取得しよう:OrdersModel

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

:OrdersLinesモデルに

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 

私は各行の最後の統計レコードを取得しません...実際には、それは私に最も古いものを与えます。私は何かを見逃しているようですが、私はそれを見つけることができません。 OrdersModelで

おかげで再び

答えて

2

経由()接合を使用していますgetLastOrderLineStat()メソッドを追加:$モデルはOrdersModelのインスタンスである場合は、使用して、最後のstatの行を取得

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

を:

$model->lastOrderLineStat 
+0

ありがとうございましたが、これは同じクエリで終わります。 SELECT * FROM(orders * FROM 'ordersLinesStats's 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()を次のように変更するだけです。

を使用すると、たとえば ためmyOrderと呼ばれるオブジェクトを持っているならば、あなたが欲しいの行にアクセスすることができます。

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

これは基本的に次のようにあなたがこれをアクセスすることができ、各注文

のためにあなたがしたい最後のOrderLinesStats行を返します。 as 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(); 
} 

hasManyhasOne自体によってだけActiveQueryオブジェクトを返すであろうActiveQueryオブジェクトの配列を返します。

あなたはとても(UserモデルにUserControllerでの例)のようにそれらを使用

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

または

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

または

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

そして、そのような関係をつかみます:

012 userPlanについては
$plan = $model->userPlan 

または

$plans = $model->userPlans 

:userPlans取り扱い

$planId = $plan->id; 

foreach($plans as $plan) { 
    $plan->id; 
} 
関連する問題