Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do an exact match followed by ORDER BY in PostgreSQL

I'm trying to write a query that puts some results (in my case a single result) at the top, and then sorts the rest. I have yet to find a PostgreSQL solution.

Say I have a table called airports like so.

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

In short, I have a query in a controller method that gets called asynchronously when a user text searches for an airport either by code or display_name. However, when a user types in an input that matches a code exactly (airport code is unique), I want that result to appear first, and all airports that also have int in their display_name to be displayed afterwards in ascending order. If there is no exact match, it should return any wildcard matches sorted by display_name ascending. So if a user types in INT, The row (2, INT, International Airport) should be returned first followed by the others:

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

Here's the kind of query I was tinkering with that is slightly simplified to make sense outside the context of my application but same concept nonetheless.

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

Right now the results if I type INT I'm getting

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

My ORDER BY must be incorrect but I can't seem to get it Any help would be greatly appreciated :)

like image 542
ElGatoGabe Avatar asked Jul 31 '17 14:07

ElGatoGabe


1 Answers

If you want an exact match on code to return first, then I think this does the trick:

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

You could also write this as:

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

This isn't standard SQL, but it is quite readable.

like image 96
Gordon Linoff Avatar answered Nov 14 '22 23:11

Gordon Linoff