@EVOSandru6

Как в Yii2 можно сделать сортировку по вычисляемому рейтингу и по кол-ву связанных данных?

Добрый вечер,

Есть такие таблицы:

users
----------------
id
name
----------------

departments
----------------
id
name
----------------

news
----------------
id
department_id
name
----------------

events
----------------
id
department_id
name
----------------

rating_departments
----------------
department_id
user_id
rate
----------------

Мне нужно сделать:

1) Вывод модели Departments по рейтингу по убыванию

2) Вывод модели Departments по убыванию кол-ва привязанных к нему новостей и событий. С учетом суммарного кол-ва и тех и тех.

Желательно скормить желаемую сортировку для DepartmentsSearch класса или хотя бы для модели

Исходные модели:

class Departments extends ActiveRecord
{
...
    public function getEvents()
    {
        return $this->hasMany(Events::className(), ['department_id' => 'id']);
    }

    public function getNews()
    {
        return $this->hasMany(News::className(), ['department_id' => 'id']);
    }

public function getRatingSum()
    {
        $val = RatingDepartments::find()->andWhere([
            'department_id' => $this->department_id,
        ])->sum('rate');
        return $val ?? 0;
    }

    public function getRatingQty()
    {
        $val = RatingDepartments::find()->andWhere([
            'department_id' => $this->department_id,
        ])->count();
        return $val;
    }

    public function getRate()
    {
        $sum = $this->getRatingSum();
        $qty = $this->getRatingQty();
        if(!$qty)
            return 0;
        $rate = ceil($sum / $qty);
        return $rate;
    }
...
}


class RatingDepartments extends ActiveRecord
{
  ...
    public function getUser()
    {
        return $this->hasOne(Users::className(), ['id' => 'user_id']);
    }

    public function getDepartment()
    {
        return $this->hasOne(Departments::className(), ['id' => 'department_id']);
    }
    ...
}


class News extends ActiveRecord
{
...
public function getDepartment()
    {
        return $this->hasOne(Departments::className(), ['id' => 'department_id']);
    }
...
}

class News extends ActiveRecord
{
...
public function getDepartment()
    {
        return $this->hasOne(Departments::className(), ['id' => 'department_id']);
    }
...
}

class Events extends ActiveRecord
{
...
public function getDepartment()
    {
        return $this->hasOne(Departments::className(), ['id' => 'department_id']);
    }
...
}


https://nix-tips.ru/yii2-sortirovka-i-filtr-gridvi... смотрел. Но этот вариант не совсем подходит, чую тут нужен какой то хитровыдуманный SQL запрос.

Также понимаю криворукость метода getRate, надо как то одним запросом результат доставать, но лучшего решения я пока не знаю.

Заранее благодарю за любую помощь
  • Вопрос задан
  • 222 просмотра
Решения вопроса 1
@EVOSandru6 Автор вопроса
В модели Departments добавил метод - примерно то, что мне надо:

public static function  getProviderByTotalParams()
    {
        $mainTable = self::tableName();

        $sql = '
             SELECT m_departments.id, m_departments.name, 
             COUNT(m_news.id) + COUNT(m_posts.id) + COUNT(m_forums.id) + COUNT(m_questions.id) AS total_count
            FROM m_departments 
            LEFT JOIN m_news ON m_departments.id = m_news.department_id
            LEFT JOIN m_posts ON m_departments.id = m_posts.department_id
            
            GROUP BY m_departments.id
            ORDER BY total_count DESC
            LIMIT 5
        ';

        $dataProvider = new SqlDataProvider([
            'sql' => $sql, 
            'totalCount' => 5, 
            'pagination' => [
                'pageSize' => 5, 
            ],
        ]);;

        return $dataProvider;
    }
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы