Текст запроса MySQL в нескольких таблицах

У меня есть две таблицы MySQL; Город и страна, я хочу, чтобы пользователь мог искать в двух таблицах что-то, что соответствует любой из них, и мне нужен порядок соответствия/релевантности качества из обеих таблиц.

(SELECT 'city' AS type, c.slug, c.name, c.city_id AS id 
FROM city c 
WHERE c.name LIKE '%ame%' 
ORDER BY CASE 
  WHEN c.name = 'ame' THEN 0
  WHEN c.name LIKE 'ame%' THEN 1 
  WHEN c.name LIKE '%ame%' THEN 2
  WHEN c.name LIKE '%ame' THEN 3 
  ELSE 4 END,
  c.name ASC
LIMIT 24 OFFSET 0)
UNION
(SELECT 'country' as type, c.slug, c.name, c.country_id AS id 
FROM country c 
WHERE c.name LIKE '%ame%'
ORDER BY CASE
  WHEN c.name = 'ame' THEN 0
  WHEN c.name LIKE 'ame%' THEN 1
  WHEN c.name LIKE '%ame%' THEN 2
  WHEN c.name LIKE '%ame' THEN 3
  ELSE 4 END,
  c.name ASC 
LIMIT 24 OFFSET 0);

Я получаю объединенный результат по двум таблицам, но я получаю все результаты по городу, затем все результаты по стране - я хочу получить его, чтобы результаты смешивались и сортировались по точности... не по городу, а по стране - или это желательно?

Особенно приветствуются любые другие способы выполнения запроса по двум таблицам, в идеале мне может потребоваться объединить таблицу с городом и таблицу со страной, чтобы добавить некоторую метаинформацию к возвращаемым данным.

Или есть лучший способ вызвать две конечные точки и иметь столбец соответствия релевантности, а затем объединить обе конечные точки в серверную часть массива json, упорядоченную по этой релевантности?

Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
0
0
21
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете обернуть UNION в подзапрос, а затем повторить порядок:

SELECT *
FROM ((SELECT 'city' AS type, c.slug, c.name, c.city_id AS id 
       FROM city c 
       WHERE c.name LIKE '%ame%' 
       ORDER BY CASE 
         WHEN c.name = 'ame' THEN 0
         WHEN c.name LIKE 'ame%' THEN 1 
         WHEN c.name LIKE '%ame%' THEN 2
         WHEN c.name LIKE '%ame' THEN 3 
         ELSE 4 END,
         c.name ASC
       LIMIT 24 OFFSET 0)
       UNION
       (SELECT 'country' as type, c.slug, c.name, c.country_id AS id 
       FROM country c 
       WHERE c.name LIKE '%ame%'
       ORDER BY CASE
         WHEN c.name = 'ame' THEN 0
         WHEN c.name LIKE 'ame%' THEN 1
         WHEN c.name LIKE '%ame%' THEN 2
         WHEN c.name LIKE '%ame' THEN 3
         ELSE 4 END,
         c.name ASC 
       LIMIT 24 OFFSET 0)) c
ORDER BY CASE
  WHEN c.name = 'ame' THEN 0
  WHEN c.name LIKE 'ame%' THEN 1
  WHEN c.name LIKE '%ame%' THEN 2
  WHEN c.name LIKE '%ame' THEN 3
  ELSE 4 END,
  c.name ASC 

Было бы более эффективно создать столбец ранжирования:

SELECT *
FROM ((SELECT 'city' AS type, c.slug, c.name, c.city_id AS id,
       CASE 
         WHEN c.name = 'ame' THEN 0
         WHEN c.name LIKE 'ame%' THEN 1 
         WHEN c.name LIKE '%ame%' THEN 2
         WHEN c.name LIKE '%ame' THEN 3 
         ELSE 4 END AS `rank`
       FROM city c 
       WHERE c.name LIKE '%ame%' 
       ORDER BY `rank`, c.name ASC
       LIMIT 24 OFFSET 0)
       UNION
       (SELECT 'country' as type, c.slug, c.name, c.country_id AS id,
       CASE 
         WHEN c.name = 'ame' THEN 0
         WHEN c.name LIKE 'ame%' THEN 1 
         WHEN c.name LIKE '%ame%' THEN 2
         WHEN c.name LIKE '%ame' THEN 3 
         ELSE 4 END AS `rank` 
       FROM country c 
       WHERE c.name LIKE '%ame%'
       ORDER BY `rank`, c.name ASC 
       LIMIT 24 OFFSET 0)) c
ORDER BY c.rank, c.name ASC

Это даст вам 48 результатов, по 24 в каждом городе и стране. Если вам просто нужны результаты с самым высоким рейтингом, независимо от того, из какой таблицы они получены, просто удалите предложения ORDER BY и LIMIT из UNION:

SELECT *
FROM ((SELECT 'city' AS type, c.slug, c.name, c.city_id AS id 
       FROM city c 
       WHERE c.name LIKE '%ame%')
       UNION
       (SELECT 'country' as type, c.slug, c.name, c.country_id AS id 
       FROM country c 
       WHERE c.name LIKE '%ame%'
       )) c
ORDER BY CASE
  WHEN c.name = 'ame' THEN 0
  WHEN c.name LIKE 'ame%' THEN 1
  WHEN c.name LIKE '%ame%' THEN 2
  WHEN c.name LIKE '%ame' THEN 3
  ELSE 4 END,
  c.name ASC 
LIMIT 48 OFFSET 0

Другие вопросы по теме