Сортировка — Порядок по Лайкам и идентификаторам из базы данных в laravel

#mysql #laravel

Вопрос:

У меня есть база данных некоторых продуктов, и в каждой строке есть столбец «Нравится». Я хочу получить предыдущие 2 записи с помощью продукта запроса. У меня есть такая база данных —

     -------- ---------- ----------- 
   |   id   |  image   |   likes   |
    -------- ---------- ----------- 
   |   16   |    A     |    80     |
    -------- ---------- ----------- 
   |   29   |    B     |    82     |
    -------- ---------- ----------- 
   |   12   |    c     |    83     |
    -------- ---------- ----------- 
   |   24   |    d     |    83     |
    -------- ---------- ----------- 
   |   30   |    f     |    83     |
    -------- ---------- ----------- 
   |   14   |    g     |    84     |
    -------- ---------- ----------- 
   |   17   |    h     |    84     |
    -------- ---------- ----------- 
   |   25   |    i     |    85     |
    -------- ---------- ----------- 
 

Я получаю данные по идентификатору, подобному этому, из базы данных-

 public function display(Request $request)
    {
        $image = $request->input('image');

        $product= Products::query()
            ->where('image', $image)
            ->firstOrFail();

        $previous = Products::where('likes', '=', $product->likes)
    ->where('id', '<', $product->id)
    ->orderBy('id', 'asc')

    ->union(
        Products::where('likes', '<', $product->likes)
        ->orderBy('likes','desc')
    )->limit(2)->get();

       

        return $previous;
    }
 

Основная проблема заключается в ОГРАНИЧЕНИИ. если идентификатор равен 12, он работает нормально, а если идентификатор равен 24, то я должен установить ограничение в «1» в 1-м запросе и 2-м запросе.

Комментарии:

1. Ваша проблема неясна, и предоставленный вами код, похоже, не имеет никакого отношения к вашему вопросу. Я ничего не вижу в этом коде о «Продукте» или «лайках».

2. @miken32 отредактировал вопрос и код.

3. @miken32 обновил вопрос с некоторым решением и ясностью.

Ответ №1:

Я думаю, что концепция, которую вы пытаетесь описать здесь, заключается в том, что вы хотите получить row number не record id то, когда вы order records находитесь в likes поле. К сожалению MySQL , у него нет собственной row number функции, поэтому вам придется проделать некоторую дополнительную работу, чтобы получить ее.

Одним из таких методов было бы выбрать записи из базы данных, упорядоченные по likes столбцу, а затем найти row number их оттуда. Предостережение к этому методу заключается в том, что вы сохраняете все свои записи в памяти. Если у вас всего несколько записей, это может не быть проблемой, однако это будет проблемой для больших наборов данных.

 /**
 * In order to limit memory consumption,
 * get just the `id` field for the records
 * order them by `likes` ascending
 */
$records = Design::orderBy('likes')->select('id')->get();

/**
 * Search the records for record with the desired `$id`
 * then return the `index` of that record in the collection
 * Note that the `index` is zero indexed
 */
$position = $records->search(function ($record) use ($id) {
    return $record->id === $id;
});

/**
 * Use the `$position` as a starting point to skip to in the `$records`,
 * subtract 2 from the `$position` and take 5 results meaning,
 * you get your desired record plus the 2 before and after it
 */
$return = $records->skip($position - 2)->take(5)->pluck('id');
 

Обновить

Вы говорите, что у вас большая база данных (так все говорят), поэтому я предполагаю, что загрузка ids в память-это не вариант. Поэтому самым простым решением, которое я мог придумать, было создать view столбец, в MySQL котором есть вычисляемый position столбец, который можно использовать в качестве точки отсчета.

 CREATE VIEW `product_rankings` AS
SELECT
  *,
  FIND_IN_SET (
    likes,(
      SELECT
        GROUP_CONCAT(
          likes
          ORDER BY
            likes ASC
        )
      FROM
        products
    )
  ) AS position
FROM
  products
  ORDER BY position, id
;
 

Затем вы можете сделать что-то вроде следующего:

 $product = DB::table('product_rankings')
    ->where('id', 12)
    ->get();

$result = DB::table('product_rankings')
    ->where('position', '<', $product->position)
    ->orderBy('likes')
    ->get();
 

Вы можете применять ограничения и смещения по своему усмотрению.

Комментарии:

1. подождите, у меня есть какое-то решение и редактирование запроса.

2.@mukeshsoni У вас всегда будут проблемы, потому что вы используете в record id качестве метода фильтрации после того, как вы упорядочили свои результаты.

3. каков наилучший подход ?

4. Я дал вам свой ответ выше. Попробовать это.

5. у меня большая база данных