1

I have been trying to figure the following for a couple days. Please HELP

PostgreSQL table : locations

Id         State

--------------------
1          New York

2          Texas

input = 'Greetings from Texas to all Cowboys'

output: row containing Texas

SELECT id, state FROM locations WHERE state ~* substring(input from state)

3 Answers 3

5

1.

select * from locations where 'Greetings from Texas to all Cowboys' ~ State;

2.

select * from locations where State = any(string_to_array('Greetings from Texas to all Cowboys',' '));

The two methods above both have some problems in some circumstances.But I want to know if they are for you.

3.

select * from locations where 'reetings from Texas to all Cowboys' ~* ('\\m' || state || '\\M');

The last method would be more better.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks guys. It works perfectly on a small table. But not on my huge table containing 1 millions locations. I think, it is indexing problem Thanks for your quick reactions
If you want this fast for large tables, then you need special indexing and other magic. See postgresql.org/docs/8.4/static/textsearch.html how to do fast, indexed full text search.
I have discovered why I had a problem. Certain rows of the colunm state has some parenthesis. select state from locations where state like '%(%' return colunms with rows How can escape the () in state
3

A search word is not a pattern. Try this:

select * from locations where 'Hello from Texas!' like '%' || state || '%';

or this:

select * from locations where 'Hello from Texas!' ~* ('.*' || state || '.*');

if you want Posix regexp's.

Example:

# create table locations(id integer, state text);
CREATE TABLE
# insert into locations values  (1,'New York'),(2,'Texas') ;
INSERT 0 2
# select * from locations where 'Hello from Texas!' like '%' || state || '%';
 id | state
----+-------
  2 | Texas
(1 row)

# select * from locations where 'Hello from Texas!' ~* ('.*' || state || '.*');
 id | state
----+-------
  2 | Texas
(1 row)

# select * from locations where 'Greetings from you ex' like '%' || state || '%';
 id | state
----+-------
(0 rows)

# select * from locations where 'Greetings from your ex' ~* ('.*' || state || '.*');
 id | state
----+-------
(0 rows)

This needs some refinement or course, if you need to detect word boundaries:

# select * from locations where 'fakulos greekos metexas' ~* ('.*' || state || '.*');
id | state
----+-------
2 | Texas

If you have regex-metacharacters (See the PostgresSQL docs for as list) in your search words, then you might need to quote them first. This look a bit weird but this is what escaping always looks like:

select regexp_replace('Dont mess (with) Texas, The Lone *',E'([\(\)\*])',E'\\\\\\1','g');

The ([\(\)\*]) is the list of characters you want to escape.

However, if you never need regular expressions in your search words, then it might be easier to use a simple string searching function like strpos():

select strpos('Dont mess (with) Texas','Texas')>0;
?column?
--------
t

select strpos('Dont mess (with) Texas','Mars')>0;
?column?
--------
f

You can use upper() if you want case insensitive compares

select strpos(upper('Dont mess (with) Texas'),upper('teXas'))>0;
?column?
--------
t

7 Comments

input like 'Greetings from your ex' will return a match for 'Texas'.
I have also try the Posix but get the following error ERROR: invalid regular expression: parentheses () not balanced SQL state: 2201B
I've added a the transcript on what I typed in to verify that I'm not telling you bullsh*t. Check your syntax.
I have discovered why I had a problem. Certain rows of the colunm State has some parenthesis New York (The place to be). How can I propely escape the () in State
@Luther, the problem with the strpos approach is that it does not allow to encode word boundaries that means locations such as 'As' will be returned. The approach with regexp_replace works but seems really inefficient in full sql: select * from locations where 'fakulos greekos metexas' ~* ('\\m' || regexp_replace(state, E'([()*])', E'\\\\\\1','g') || '\\M');
|
1

I would take a look at full text search:

SELECT 
    id, 
    state 
FROM 
    locations 
WHERE  
    to_tsvector('english', 'Greetings from Texas to all Cowboys') @@ plainto_tsquery('english', state);

Standard available as of version 8.3, in older versions you have to install tsearch2 from the contrib.

http://www.postgresql.org/docs/current/interactive/textsearch.html

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.