Yii2:select 来自 hasMany 关系的最后一条记录
Yii2: select last record from a hasMany relation
我对 mysql 的了解非常基础,现在我正面临一个 "complex"(对我而言)的查询,我卡在其中,所以如果有人能给我一些说明,请提前致谢。
我有三个表:
订单
id | name | comments | ...
订单行
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');
}
订单模型:
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 中添加使用 via() 连接的 getLastOrderLineStat() 方法:
public function getLastOrderLineStat()
{
return $this->hasOne(OrdersLinesStats::className(), ['lineID' => 'id'])
->orderBy(['id'=>SORT_DESC])
->groupBy('lineID')
->via('ordersLines');
}
如果 $model 是一个 OrdersModel 实例,您可以使用以下方法获取最后一个统计行:
$model->lastOrderLineStat
您需要做的就是将 getLastOrdersLinesStats()
更改为如下:
public function getLastOrdersLinesStats()
{
return $this->hasMany(OrdersLinesStats::className(), ['lineID' => 'id'])
->orderBy(['id'=>SORT_DESC])
->one();
}
这基本上是 returns 每个订单所需的最后一个 OrderLinesStats 行
您可以通过以下方式访问:
例如,如果您有一个名为 myOrder
的对象
然后你可以访问你想要的行 myOrder->lastOrderLinesStats
我只是为了彻底回答这个问题,希望能帮助其他偶然发现此页面的人。
我建议始终包括 hasOne
和 hasMany
。这样,您可以弹出顶部记录,或检索所有记录。
/**
* @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
将 return 一个 ActiveQuery 对象数组,其中 hasOne
将 return 本身只是一个 ActiveQuery 对象。
你像这样使用它们(用户模型上的 UserController 中的示例):
$model = $this->findOne($id);
或
$model = User::findOne($id);
或
$model = User::find()->where(['id' => $id])->one();
然后像这样抓取关系:
$plan = $model->userPlan
或
$plans = $model->userPlans
对于用户计划:
$planId = $plan->id;
处理用户计划:
foreach($plans as $plan) {
$plan->id;
}
我对 mysql 的了解非常基础,现在我正面临一个 "complex"(对我而言)的查询,我卡在其中,所以如果有人能给我一些说明,请提前致谢。
我有三个表:
订单
id | name | comments | ...
订单行
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');
}
订单模型:
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 中添加使用 via() 连接的 getLastOrderLineStat() 方法:
public function getLastOrderLineStat()
{
return $this->hasOne(OrdersLinesStats::className(), ['lineID' => 'id'])
->orderBy(['id'=>SORT_DESC])
->groupBy('lineID')
->via('ordersLines');
}
如果 $model 是一个 OrdersModel 实例,您可以使用以下方法获取最后一个统计行:
$model->lastOrderLineStat
您需要做的就是将 getLastOrdersLinesStats()
更改为如下:
public function getLastOrdersLinesStats()
{
return $this->hasMany(OrdersLinesStats::className(), ['lineID' => 'id'])
->orderBy(['id'=>SORT_DESC])
->one();
}
这基本上是 returns 每个订单所需的最后一个 OrderLinesStats 行
您可以通过以下方式访问:
例如,如果您有一个名为 myOrder
的对象
然后你可以访问你想要的行 myOrder->lastOrderLinesStats
我只是为了彻底回答这个问题,希望能帮助其他偶然发现此页面的人。
我建议始终包括 hasOne
和 hasMany
。这样,您可以弹出顶部记录,或检索所有记录。
/**
* @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
将 return 一个 ActiveQuery 对象数组,其中 hasOne
将 return 本身只是一个 ActiveQuery 对象。
你像这样使用它们(用户模型上的 UserController 中的示例):
$model = $this->findOne($id);
或
$model = User::findOne($id);
或
$model = User::find()->where(['id' => $id])->one();
然后像这样抓取关系:
$plan = $model->userPlan
或
$plans = $model->userPlans
对于用户计划:
$planId = $plan->id;
处理用户计划:
foreach($plans as $plan) {
$plan->id;
}