13

I have following data in table:

+----------------------+----------------------------------------------------------+--------------+
| subscriber_fields_id | name                                                     | field_type   |
+----------------------+----------------------------------------------------------+--------------+
|                  143 | Peshawar/Islamabad/Lahore/Swat/Mardan/Karachi            | Job Location |
|                  146 | Karachi                                                  | Job Location |
|                  147 | Lahore and Karachi                                       | Job Location |
|                  149 | Karachi, Mirpur Khas, Sukkur, Layyah, Gilgit, Charsaddah | Job Location |
|                  152 | Islamabad or Lahore                                      | Job Location |
|                  155 | Islamabad                                                | Job Location |
|                  157 | 7 Districts of Sindh and Karachi                         | Job Location |
+----------------------+----------------------------------------------------------+--------------+

My query is:

select * from subscriberfields
where  name like '%Khairpur,Islamabad,Karachi%';

Result:

+----------------------+-----------------------------------------------+--------------+
| subscriber_fields_id | name                                          | field_type   |
+----------------------+-----------------------------------------------+--------------+
|                  143 | Peshawar/Islamabad/Lahore/Swat/Mardan/Karachi | Job Location |
|                  152 | Islamabad or Lahore                           | Job Location |
|                  155 | Islamabad                                     | Job Location |
+----------------------+-----------------------------------------------+--------------+

It should return all rows where the name includes Islamabad, Khairpur or Karachi but it is not.

3
  • You want WHERE name LIKE '%Khairpur%' OR name LIKE .... However, it is not sargable and therefore will require a full table scan—it will become desperately inefficient as the table size grows. You should consider using fulltext search instead. Commented Mar 9, 2015 at 9:52
  • Have you tried SIMILAR TO like I've suggested in the answer? Commented Mar 9, 2015 at 10:22
  • 1
    @gudthing: Never use SIMILAR TO, it's an utterly pointless construct - there is always a better option. I added an answer. Commented Mar 9, 2015 at 13:04

5 Answers 5

26

For a proper solution, either normalize your database design or, barring that, consider full text search.

For a quick solution to the problem at hand, use a regular expression match (~) or three simple LIKE expressions:

SELECT *
FROM   subscriberfields 
WHERE  name ~ '(Khairpur|Islamabad|Karachi)';

Or:

WHERE (name LIKE '%Khairpur%'
    OR name LIKE '%Islamabad%'
    OR name LIKE '%Karachi%')

.. which can be compressed like Mario demonstrates in his answer. Or shorter, yet, with an array literal:

WHERE name LIKE ANY ('{%Khairpur%, %Islamabad%, %Karachi%}');

But the regexp match gets the same query plan in modern Postgres (can use the same trigram index) and is shorter, yet. See:

Or use ~* or ILIKE for case-insensitive matching.

Since another answer suggested it: never use SIMILAR TO:

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

Comments

5

You can use this:

select * from subscriberfields
where  name like any(array['%Khairpur%','%Islamabad%','%Karachi%']);

https://postgres.cz/wiki/PostgreSQL_SQL_Tricks#LIKE_to_list_of_patterns

Comments

3

Try using SIMILAR TO like below:

SELECT * FROM subscriberfields 
WHERE name SIMILAR TO '%(Khairpur|Islamabad|Karachi)%';

Also you should read up on database normalization. Your design could and should definitely be improved.

Comments

0

In MySQL try using a regular expression "REGEXP" and operator | which works like OR:

SELECT * FROM subscriberfields  WHERE  name REGEXP 'Khairpur|Islamabad|Karachi';

so you will get results containing at least one of these words.

Alternatively, if you want results that will include ALL words, use:

SELECT * FROM subscriberfields  WHERE  name REGEXP '(?=.*Khairpur)(?=.*Islamabad)(?=.*Karachi)';

Works with MySQL on server version 10 MariaDB and PHP 8

If you want to learn more about REGEXP try:

https://www.geeksforgeeks.org/mysql-regular-expressions-regexp/ https://www.freecodecamp.org/news/sql-contains-string-sql-regex-example-query/

There are many blogs with REGEXP examples, but not everyone will give you all the patterns and values you can use, but for starters, have a look at these.

Comments

-1

Use OR in WHERE clause, like,

select * from subscriberfields where name like '%Khairpur%' OR name like '%Islamabad%' OR name like '%Karachi%';

Hope it works.

3 Comments

no, the value is coming from database, i cannot split it by commas because sometimes it is split by , , /, - etc.
@MTaqi: This sounds like very poor database design indeed. You may like to read up to database normalization and also take a look at Is storing a delimited list in a database column really that bad?
In that case you really need to consider FULLTEXT Searching, as suggested by eggyal.

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.