Reputation: 743
I'm using Postgres and suppose I have a simple table like this
cities
------------------
id | name
------------------
1 | San Diego
------------------
2 | San Antonio
------------------
3 | Stockholm
------------------
4 | Helsinki
------------------
5 | San Francisco
------------------
I would like to find all cities that exactly or partially matched to the pattern. And it is important that exactly matched city should be the first in the result. For example if I find city for "San Francisco" the result should be like this
-------------------
id | name
-------------------
5 | San Francisco
-------------------
1 | San Diego
-------------------
2 | San Antonio
-------------------
It is important that "San Francisco" is the first in the result.
My query looks like this
SELECT * FROM cities WHERE name = "San Francisco"
UNION
SELECT * FROM cities WHERE name ~* "San|Francisco"
But this query doesn't guarantee desired order. I tryied to use Partitions to add row_number() and order by it.
WITH cities_with_rows_number AS (
SELECT *, 0 as row_number FROM cities WHERE name = "San Francisco"
UNION
SELECT *, row_number() OVER() as row_number FROM cities WHERE name ~* "San|Francisco"
) SELECT * FROM cities_with_rows_number ORDER BY row_number
But in this case I can't easy eleminate duplicate cities and "San Francisco" will be printed twice. I belive it is possible to write quite simple query to resolve this task.
Upvotes: 0
Views: 28
Reputation: 1271111
You can use order by
:
SELECT *
FROM cities
WHERE name ~* 'San|Francisco'
ORDER BY (name = 'San Francisco')::int DESC;
UNION
/UNION ALL
is not needed for this query.
Upvotes: 2