Eloquent / SQL - получить номер строки запроса (ранг) - PullRequest
2 голосов
/ 26 марта 2019

Хотелось бы узнать ранг на основе структуры моей БД:

У меня есть модель Post, принадлежащая модели с именем Edition (также one Edition имеет много Post).

Один Post имеет много Like.

Я хотел бы знать ранг Post на основе подсчета Like внутри определенного Edition.

код:

// Define the id of an edition
$edition_id = 53;
// The id of the post to retrieve rank
$post_id = 132;
// Compose the query by select all posts, of interested edition ...
$query = App\Models\Post::where('edition_id', $edition_id)
    // ... with like count (this produce an additional field named likes_count) ...
    ->withCount('likes')
    // ... in descendig order by this count.
    ->orderBy('likes_count', 'desc');
// By execute it I can get right results.
$query->get();

Для людей, которые не знакомы с Laravel Eloquent ORM, я сообщаю SQL-запрос, выполненный из кода выше:

select `posts`.*, (select count(*) from `likes` where `posts`.`id` = `likes`.`post_id` and `likes`.`deleted_at` is null) as `likes_count`
from `posts`
where `edition_id` = '53' and `posts`.`deleted_at` is null
order by `likes_count` desc

Я сообщаю результаты запроса:

=> Illuminate\Database\Eloquent\Collection {#994
all: [
    App\Models\Post {#993
        id: 135,
        likes_count: 4,
    },
    App\Models\Post {#1075
        id: 134,
        likes_count: 3,
    },
    App\Models\Post {#1091
        id: 133,
        likes_count: 2,
    },
    App\Models\Post {#997
        id: 132,
        likes_count: 1,
    },
    App\Models\Post {#1038
        id: 131,
        likes_count: 0,
    },
],
}

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

Например, как получить результат ранга записи с помощью id = 132?

Ответы [ 2 ]

1 голос
/ 02 апреля 2019

Вы можете использовать подзапрос:

$query = Post::where('edition_id', $edition_id)
    ->withCount('likes')
    ->selectRaw('@rank := @rank + 1 rank')
    ->from(DB::raw('`posts`, (SELECT @rank := 0) vars'))
    ->orderBy('likes_count', 'desc');

$posts = Post::fromSub($query, 'posts')->paginate();

$post = Post::fromSub($query, 'posts')->find($post_id);

Обходной путь для Laravel <5.6: </p>

Builder::macro('fromSub', function($query, $as) {
    $this->bindings = array_merge(
        array_slice($this->bindings, 0, 1),
        ['from' => $query->getBindings()],
        array_slice($this->bindings, 1)
    );

    $sql = '('.$query->toSql().') as '.$this->grammar->wrap($as);

    return $this->from(DB::raw($sql));
});
0 голосов
/ 26 марта 2019

Вы можете использовать метод search () , чтобы найти ключ:

Метод поиска ищет в коллекции заданное значение и возвращает его ключ, если он найден.Если элемент не найден, возвращается false.

$id = 132;

$key = $query->search(function($post,$id) {
    return $post->id === $id;
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...