views:

111

answers:

3

Hello, I am trying to filter results in an sql query using the like statement. Here are the results

/q/my_rat_terrior_is_about_8_just_this_moring_hes_barley_moving_around_panting_heavy_and_shaking_like_shivering/1
/addquestion
/addquestion/Validation
/q/how_do_you_get_a_hamster_out_of_a_wall/2

These are urls that are stored in my database. I want to match urls like these

/q/how_do_you_get_a_hamster_out_of_a_wall/2
/q/my_rat_terrior_is_about_8_just_this_moring_hes_barley_moving_around_panting_heavy_and_shaking_like_shivering/1

This is what I have tried:

select * from MyURLs where MYuri LIKE '/q/'

But its not returning any results. Any Ideas on this?

+3  A: 

You need to use % as a wildcard:

select * from MyURLs where MYuri LIKE '%/q/%'

That would return records with a '/q/' anywhere in the field. If you want it to start with '/q/' but have anything after that, you would use:

select * from MyURLs where MYuri LIKE '/q/%'
Kaleb Brasee
Be careful with filters like this: `'%/q/%'`, where there's a wild card at the front of the filter. That will break indexes.
Joel Coehoorn
+2  A: 

Kaleb has already given you the solution (and Joel has warned about index performance in the comment) but I'd like to suggest another route, one that will scale well. If your tables are never going to get to be very large, you can ignore this advice. In fact, you can ignore it right up until the time when you expect performance will suffer (or performance has actually started suffering) - this is the YAGNI principle.

Databases are almost always read far more than they're written. This means that the right time to figure out when the URL starts with, or contains, a "/q/" is when the data is put in the table, not every single time you extract it. This amortizes the cost of the calculation (done at write time) across all the reads.

For this scalable solution, you should have a totally separate column in the table, something like "startsWithQ" or "hasQ".

Then, with an insert/update trigger, set that column based on the URL being put into the table.

Then your query will become:

select * from MyURLs where hasQ = 'YES'

and, provided you have an index on that column, your queries will scream along.

If you actually look at most database problems, they're usually "my query isn't fast enough" rather than "my disk isn't big enough". Trading disk space for speed is usually the best approach.

This may provide a performance improvent if your search string is '/q/%'. This should be profiled, regularly and in production - databases are rarely set-and-forget since performance can change based on the data in the tables - measure, don't guess.

It will certainly provide an improvement if the search string is '%/q/%', unless your database is one of those very rare beasts that has more writes than reads.

paxdiablo
whoa..This is a good idea. I will use this technique with other solutions. But what Im actually doing is reading the iis log file so I would be inserting any data. But this is truelly a good idea for other solutions
Luke101
Yeah, that is a very good idea if you know what your searches will be up front, or have the ability to retroactively modify an existing table. I've worked with quite a few tables (usually audit data) where I need to search for a particular type of audit record, but I can only find those records by doing a LIKE at the beginning or middle of a varchar... talk about a slow query!Then again, these systems get a LOT more audit inserts than they get queries. It would be interesting to see what the performance cost is in doing the LIKE for every insert, when doing 100,000 inserts per day.
Kaleb Brasee
Agree, part of designing a database is creating the structure you need so that you don't ever have to search using like '%sometext%'
HLGEM
+1  A: 

If you have a lot text like this, create a full-text catalog, create and populate a full-text index, then query full-text data. its key words: contains, freetext, containstable, freetexttable. sql server 2005 and 2008 have powerful free-text search.

Henry Gao