18

How can I check for a substring in a string in Oracle without using LIKE? Let's say I want to select all users from a table that have the letter "z" in their last name:

SELECT * FROM users WHERE last_name LIKE '%z%';

That would work, but I don't want to use LIKE. Is there some other function I could use?

1
  • Why don't you want LIKE? What is the problem with LIKE you're trying to get around? Commented Aug 16, 2022 at 13:31

6 Answers 6

16

I'm guessing the reason you're asking is performance? There's the instr function. But that's likely to work pretty much the same behind the scenes.

Maybe you could look into full text search.

As last resorts you'd be looking at caching or precomputed columns/an indexed view.

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

7 Comments

My guess is that full text search won't buy you anything. It usually indexes words, not substrings.
To be honest, I've never tried Oracle's. I'd hope it supports some kind of wildcard system though. I know SQL Server's full text does
Yes, it's because performance. I'm looking for something like strstr() in PHP.
Can you get away with LIKE "z%"; at least that way you can use an index on the column?
What makes you think something like strstr would be any faster over a large dataset than LIKE?
|
8

If you were only interested in 'z', you could create a function-based index.

CREATE INDEX users_z_idx ON users (INSTR(last_name,'z'))

Then your query would use WHERE INSTR(last_name,'z') > 0.

With this approach you would have to create a separate index for each character you might want to search for. I suppose if this is something you do often, it might be worth creating one index for each letter.

Also, keep in mind that if your data has the names capitalized in the standard way (e.g., "Zaxxon"), then both your example and mine would not match names that begin with a Z. You can correct for this by including LOWER in the search expression: INSTR(LOWER(last_name),'z').

1 Comment

Even more efficient would be to only index the rows with z ... CREATE INDEX users_z_idx ON users (Case when INSTR(last_name,'z')> 0 then 1 else null end))
7

You can do it this way using INSTR:

SELECT * FROM users WHERE INSTR(LOWER(last_name), 'z') > 0;

INSTR returns zero if the substring is not in the string.

Out of interest, why don't you want to use like?

Edit: I took the liberty of making the search case insensitive so you don't miss Bob Zebidee. :-)

Comments

2

Databases are heavily optimized for common usage scenarios (and LIKE is one of those).

You won't find a faster way of doing your search if you want to stay on the DB-level.

Comments

0

Bear in mind that it is only worth using anything other than a full table scan to find these values if the number of blocks that contain a row that matches the predicate is significantly smaller than the total number of blocks in the table. That is why Oracle will often decline the use of an index in order to full scan when you use LIKE '%x%' where x is a very small string. For example if the optimizer believes that using an index would still require single-block reads on (say) 20% of the table blocks then a full table scan is probably a better option than an index scan.

Sometimes you know that your predicate is much more selective than the optimizer can estimate. In such a case you can look into supplying an optimizer hint to perform an index fast full scan on the relevant column (particularly if the index is a much smaller segment than the table).

SELECT /*+ index_ffs(users (users.last_name)) */
       * 
FROM   users
WHERE  last_name LIKE "%z%"

Comments

0

try using the function REGEXP_INSTR

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

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.