#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. у меня большая база данных