Home > Mobile >  Get all records where each words in string exists on any of the columns in a table
Get all records where each words in string exists on any of the columns in a table

Time:01-07

I am building a search functionality and need help with a postgres query. My use case is - When a string is an input, what is the best (optimized) way in postgres to get all records where each words in string exists on any of the columns in a table ?

Sample Table: (The table I am working with has 40 columns)

FName Occupation
John Engineer
Carlos Doctor

Case 1: Given a string 'John Doctor', In this case it would return both the records.

Output:

FName Occupation
John Engineer
Carlos Doctor

Case 2: Given a string 'John Engineer', it would only return 1 row

Output:

FName Occupation
John Engineer

Case 3: Given a string 'Carlos', it would return 1 row

Output:

FName Occupation
Carlos Doctor

CodePudding user response:

Basically, you want to do following:

SELECT FName, Occupation
FROM yourtable
WHERE 
'John' IN (FName, Occupation) OR
'Doctor' IN (FName, Occupation);

I don't know if this is already a sufficient answer for you because it's unclear if the logic to fetch the different names from your "search string" must be written as SQL query, too. I think that's a much better task for your application.

If this must also be done in pure SQL, you could use UNNEST to split your string. Something like this:

WITH sub AS
(SELECT UNNEST(STRING_TO_ARRAY('John Doctor', ' ')) AS searchNames)
SELECT 
DISTINCT y.FName, y.Occupation 
FROM yourtable y, sub 
WHERE
sub.searchNames IN (y.FName, y.Occupation);

This will split your string by spaces into the different names, i.e. you need to provide a search string in the form you have mentioned, with a space between the names. This will produce the correct results according to your description.

We can verify this here: db<>fiddle1

This can be extended for as many column as needed. Let's for example add a further column col and search Test3 in this column, then the query will be like this:

SELECT FName, Occupation,col
FROM yourtable
WHERE 'John' IN (FName, Occupation, col)
OR 'Doctor' IN (FName, Occupation, col)
OR 'Test3' IN (FName, Occupation, col);

Or again with UNNEST like this:

WITH sub AS
(SELECT UNNEST(STRING_TO_ARRAY('John Doctor Test3', ' ')) AS searchNames)
SELECT 
DISTINCT y.FName, y.Occupation, y.col 
FROM yourtable y, sub 
WHERE
sub.searchNames IN (y.FName, y.Occupation, y.col);

Try this here: db<>fiddle2

CodePudding user response:

Use regexp match operator (case insensitive) and any to find the records that contain at least one of the words in the list.

select * 
from the_table t
where t::text ~* any(string_to_array(the_words_list, ' '));

DB Fiddle demo

  • Related