我有两个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阵列服务器端?
答案 0 :(得分: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