сначала точное соответствие, затем связанные данные в подобном запросе mysql laravel-5 - PullRequest
0 голосов
/ 25 апреля 2018

Я проверил это , это ссылки для решения, но не могу найти подходящее для меня.

Я пытаюсь получить записи, в которых сначала есть точные совпадения, а затем соответствующие совпадения.

Вот то, что я пробовал до сих пор.

$facility = DB::table('facility')
    ->select('ID', 'Name', 'Address', 'Phone', 'Latitude', 'Longitude')
    ->where('Name', 'like', $q . '%')
    ->where('Name', '!=', '')
    ->limit(10)
    ->get();
if(empty($facility)) {
    $facility1 = DB::table('facility')
    ->select('ID', 'Name', 'Address', 'Phone', 'Latitude', 'Longitude')
    ->where('Name', 'like', '%' . $q . '%')
    ->where('Name', '!=', '')
    ->limit(10)
    ->get();
}
$facility->{'facility1'} = $facility1;

Я пытался объединить эти 2 объекта. Но я не получаю желаемый результат.

Есть ли способ получить вывод только одним запросом?

РЕДАКТИРОВАТЬ : т.е. я просто хочу сначала получить записи с точным соответствием, а затем другие записи. Например, если я ищу «OOS», то первой записью должно быть «OOS Healthcare», а затем «Fat loss».

Ответы [ 2 ]

0 голосов
/ 30 января 2019

Второй вопрос, который вы упомянули Гвозди это ИМХО.

Мне удалось использовать его в Laravel с выражением orderByRaw Eloquent.

$facility1 = DB::table('facility')
->select('ID', 'Name', 'Address', 'Phone', 'Latitude', 'Longitude')
->where('Name', 'like', '%' . $q . '%')
->where('Name', '!=', '')
->orderByRaw("(Name = '{$q}') desc, length(Name)")
->limit(10)
->get();

Это получит все термины, такие как тот, что вам нужен, с точным соответствием вверху. Если ни одно из них не является точным совпадением, он просто вернет 10 лучших.

Вот выдержка из моего приложения:

$term = Term::where('title', 'LIKE', "%" . strtolower($query) . "%")
           ->orderByRaw("(title = '{$query}') desc, length(title)")
           ->first();
0 голосов
/ 25 апреля 2018

Я думаю создать запрос, в котором вы проверяете оба лайка, а затем выбираете псевдостолбец в результате того, что первый «лайк» совпадает, если «ложь», вы можете предположить, что второй совпадает. Затем просто упорядочите по псевдостолбцу.

В сыром MySQL я думаю, что это будет:

SELECT ID, Name, Address, Phone, Latitude, Longitude,
IF(name = '$q',2,IF(name LIKE '$q%',1,0)) as `MatchStrength`
FROM facility
WHERE name like '%$q%' AND name != ''
ORDER BY MatchStrength DESC LIMIT 10

Вы также можете сделать это без дополнительного столбца:

SELECT ID, Name, Address, Phone, Latitude, Longitude
FROM facility
WHERE name like '%$q%' AND name != ''
ORDER BY IF(name = '$q',2,IF(name LIKE '$q%',1,0)) DESC LIMIT 10

Преобразование этого в логику ORM является еще одной проблемой. Можно попробовать запустить как сырой SQL с DB::select

Это некрасиво и, вероятно, уязвимо для SQL-инъекций, но сделайте это, чтобы узнать, не приведет ли оно вас куда-либо:

$facility = DB::table('facility')
    ->select('ID', 'Name', 'Address', 'Phone', 'Latitude', 'Longitude')
    ->where('Name', 'like', "%{$q}%")
    ->where('Name', '!=', '')
    ->orderByRaw("IF(name = '{$q}',2,IF(name LIKE '{$q}%',1,0)) DESC")
    ->limit(10)
    ->get();

Возможно, можно переключиться на подготовленные запросы, выполнив конкатенацию в MySQL, используя CONCAT

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...