database - 按具有活动记录 yii2 的计算字段排序
问题描述
我有线程和线程上的消息
我想返回最后一条消息时间的所有线程,所以我在线程模型上添加了一个这样的新字段
public function fields()
{
$fields= ['idThread', 'idUser', 'title', 'unread', 'username','lastMesageTime'];
return $fields;
}
现在用这种方法我得到计算值 lastMessageTime
public function getLastMessageTime()
{
return $this->hasMany(Messages::className(), ['idThread' => 'idThread'])
->select('time')->orderBy('time DESC')->limit(1)->scalar();
}
在我的索引方法上使用这样的活动记录
return Thread::find()->select('idThread, title, idUser')->all();
这行得通,我得到了具有正确值的 lastMessageTime,但我想按顺序排序,这样我就可以得到第一个具有最新 lastMessageTime 的线程,我尝试使用以下代码
public function scopes() {
return array(
'byOrden' => array('order' => 'lastTimeMessage DESC'),
);
}
任何的想法?
编辑:这个解决方法有效,但我认为这不是一个好方法,因为我没有使用活动记录,所以我在线程模型上定义的用户名等字段我不得不再次获取它
$query = (new \yii\db\Query());
$query->select('*, (SELECT max(time) as lastMessageTime from messages where messages.idThread = thread.idThread ) lastMessageTime,
(SELECT name from users where users.idUser = thread.idUser) as name ')
->from('threads')
->where(['idUser'=>$idUser])
->orderBy('lastMessageTime DESC');
$rows = $query->all();
return $rows;
解决方案
您可以将额外的字段定义为模型属性,然后重写 find 方法为它们加载数据。
class Thread extends \yii\db\ActiveRecord
{
public $lastMessageTime;
public static function find()
{
$q = parent::find()
->select('*')
->addSelect(
new \yii\db\Expression(
'(SELECT max(time) FROM messages WHERE messages.idThread = thread.idThread) AS lastMessageTime'
);
return $q;
}
}
然后你可以像这样加载和订购模型:
$rows = Thread::find()->orderBy(['lastMessageTime' => SORT_DESC])->all();
推荐阅读
- php - Woocommerce如何删除包含文件中的功能
- node.js - React 重定向到同一路由时不会重新渲染
- python - 根据计数熊猫的条件按计数分组
- rust - 使用 cargo 命令覆盖 Cargo.toml 清单中的键
- r - r中的自动字符串匹配和替换
- python-3.x - 如何使用 iterrows 解决熊猫问题
- dspace - 在 weblogic 中安装 Dspace 6.3
- python - Python file.csv 在列表中读取和转换
- javascript - Electron Js 屏幕捕获(录制)
- reverse-engineering - JTAG flash 读/写如何在 MAXII EPM240 上工作,例如