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

我只是为了彻底回答这个问题,希望能帮助其他偶然发现此页面的人。

我建议始终包括 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 将 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;
}