如何在PostgreSQL中进行完全匹配,然后是ORDER BY

时间:2017-07-31 14:18:32

标签: sql postgresql sql-order-by case-when columnsorting

我试图编写一个查询,将一些结果(在我的情况下是单个结果)放在顶部,然后对其余结果进行排序。我还没有找到PostgreSQL解决方案。

假设我有一个名为airports的表,就像这样。

 id | code |        display_name         
----+------+----------------------------
  1 | SDF  | International               
  2 | INT  | International Airport       
  3 | TES  | Test                        
  4 | APP  | Airport Place International

简而言之,我在控制器方法中有一个查询,当用户文本按codedisplay_name搜索机场时,该方法会异步调用。但是,当用户输入与code完全匹配的输入(机场代码是唯一的)时,我希望首先显示该结果,并且int中的所有机场都有display_name随后以升序显示。如果没有完全匹配,则应返回按display_name升序排序的任何通配符匹配。因此,如果用户输入INT,则应首先返回行(2, INT, International Airport),然后返回其他行:

Results:
1. INT | International Airport
2. APP | Airport Place International
3. SDF | International

这里我正在修改的那种查询略微简化,以便在我的应用程序的上下文之外有意义,但仍然是相同的概念。

SELECT * FROM airports
WHERE display_name LIKE 'somesearchtext%'
ORDER BY (CASE WHEN a.code = 'somesearchtext` THEN a.code ELSE a.display_name END)

现在,如果我输入INT,我会得到结果

Results:
1. APP | Airport Place International
2. INT | International Airport
3. SDF | International

我的ORDER BY必须不正确,但我似乎无法得到它 任何帮助将不胜感激:)

2 个答案:

答案 0 :(得分:4)

如果你希望code上的完全匹配首先返回,那么我认为这就是诀窍:

SELECT a.*
FROM airports a
WHERE a.display_name LIKE 'somesearchtext%'
ORDER BY (CASE WHEN a.code = 'somesearchtext' THEN 1 ELSE 2 END),
         a.display_name

您也可以将其写为:

ORDER BY (a.code = 'somesearchtext') DESC, a.display_name

这不是标准的SQL,但它非常易读。

答案 1 :(得分:0)

我认为您可以通过使用UNION来实现目标。 首先获得完全匹配,然后将结果添加到其余数据中。

例如......(你需要稍微努力一下)

SELECT * FROM airports
WHERE code == 'somesearchtext'
ORDER BY display_name 

UNION

SELECT * FROM airports
WHERE code != 'somesearchtext' AND display_name LIKE 'somesearchtext%'
ORDER BY display_name