How to find an exact string within a mysql column - mysql

I have a question, what is the best way to find an exact string match within a column.
I tried using locate('needle', 'haystack') > 0. The problem with this is, for instance if the string I am trying to find is something like 'Ed', but inside a blob or a text column, I have a string that says 'I lived', locate() would return 6. However, this is not what I am asking. In an exact match, it would be best to use LIKE '', however, LIKE has it's performance issues, therefore, it is not a viable solution.
Is there a way I an use LOCATE() to do an exact match?

You can use this:
WHERE CONCAT(' ', column, ' ') LIKE BINARY '% string_to_find %'
or using LOCATE:
WHERE LOCATE(BINARY ' Ed ', CONCAT(' ', column, ' '))
Using BINARY will force an exact case matching. I think that performance of LOCATE or LIKE will be very similar. Please see fiddle here.

Related

how to handle white spaces in sql

I want to write an SQL query that will fetch all the students who live in a specific Post Code. Following is my query.
SELECT * FROM `students` AS ss WHERE ss.`postcode` LIKE 'SE4 1NA';
Now the issue is that in database some records are saved without the white space is postcode, like SE41NA and some may also be in lowercase, like se41na or se4 1na.
The query gives me different results based on how the record is saved. Is there any way in which I can handle this?
Using regexp is one way to do it. This performs a case insensitive match by default.
SELECT * FROM students AS ss
WHERE ss.postcode REGEXP '^SE4[[:space:]]?1NA$';
[[:space:]]? matches an optional space character.
REGEXP documentation MySQL
Whether case matters depends on the collation of the string/column/database/server. But, you can get around it by doing:
WHERE UPPER(ss.postcode) LIKE 'SE4%1NA'
The % will match any number of characters, including none. It is a bit too general for what you might really need -- but it should work fine in practice.
The more important issue is that your database does not validate the data being put into it. You should fix the application so the postal codes are correct and follow a standard format.
Use a combination of UPPER and REPLACE.
SELECT *
FROM students s
WHERE UPPER(REPLACE(s.postcode, ' ', '')) LIKE '%SE41NA%'
SELECT * FROM students AS ss
WHERE UPPER(REPLACE(ss.postcode, ' ', '')) = 'SE41NA' ;
SELECT *
FROM students AS ss
WHERE UPPER(ss.postcode) LIKE SELECT REPLACE(UPPER('SE4 1NA'), ' ', '%'); ;
I propose using the spaces replaced with the'%' placeholder. Also transform the case to upper for both sides of the LIKE operator

Replace a part of a file path in a string field with SQL

Hello I have a table Gallery with a field url_immagine and I would like to use a query to replace all values that look like upload/gallery/311/ge_c1966615153f6b2fcf5d84c1e389eea8.jpg in /ge_c1966615153f6b2fcf5d84c1e389eea8.jpg
Unfortunately the a part of the string, the ID (331) is not always the same and therefore can not understand how ...
I tried the regular expression like this:
UPDATE gallery SET url_immagine = replace(url_immagine, 'upload/gallery/.*/', '/')
but it seem not to work.
Combine CONCAT and SUBSTRING_INDEX since you can use last index of "/"
UPDATE gallery
SET url_immagine = (SELECT CONCAT('/',SUBSTRING_INDEX(url_immagine, '/', -1)));
Try that to confirm it's doing what you want :
SELECT CONCAT('/',SUBSTRING_INDEX(url_immagine, '/', -1))
FROM gallery
You can see documentation for the replace function and all other string functions in the mysql manual:
https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_replace
It does not mention that replace handles regular expressions, so we an assume it does not, and it is working verbatim and uses the your * to look for the char *.
You see also that there seem not to be a function that does the whole job for you. So you must somehow combine them. The idea of Mateo is probably the right direction.

Replacing substrings in MySQL

I have some sentences in string in MySQL. And I need to replace substrings such as 'My' to 'my' if this word not first in sentence. How I can doing this?
CHAR, REPLACE, REPEAT, etc. I'd recommend reading mySQL ref: http://dev.mysql.com/doc/refman/5.5/en/string-functions.html
If you just want to replace several words, you can replace them, using this approach:
UPDATE str_test SET str = REPLACE(str, ' My', ' my')
fiddle
As the words inside the text will be preceded by space. But if you want a regexp replace, it will be a more difficult task:
How to count words in MySQL / regular expression replacer?
https://dba.stackexchange.com/questions/15250/how-to-do-a-case-sensitive-search-in-where-clause
MySql support for string is very limited. A quick solution would be to use something like this:
SELECT
CONCAT(
LEFT(col, 1),
REPLACE(SUBSTRING(col, 2), 'My', 'my')
)
Please see fiddle here. This will replace all the strings My to my, except the first one.
Or maybe this:
SELECT
col,
RTRIM(REPLACE(CONCAT(col, ' '), ' My ', ' my '))
FROM
yourtable
that will replace all whole words except the first one.

SQL LIKE wildcard space character

let's say I have a string in which the words are separated by 1 or more spaces and I want to use that string in and SQL LIKE condition. How do I make my SQL and tell it to match 1 or more blank space character in my string? Is there an SQL wildcard that I can use to do that?
Let me know
If you're just looking to get anything with atleast one blank / whitespace then you can do something like the following WHERE myField LIKE '% %'
If your dialect allows it, use SIMILAR TO, which allows for more flexible matching, including the normal regular expression quantifiers '?', '*' and '+', with grouping indicated by '()'
where entry SIMILAR TO 'hello +there'
will match 'hello there' with any number of spaces between the two words.
I guess in MySQL this is
where entry RLIKE 'hello +there'
I know this is late, but I never found a solution to this in relation to a LIKE question.
There is no way to do what you're wanting within a SQL LIKE. What you would have to do is use REGEXP and [[:space:]] inside your expression.
So to find one or more spaces between two words..
WHERE col REGEXP 'firstword[[:space:]]+secondword'
Another way to match for one or more space would be to use [].
It's done like this.
LIKE '%[ ]%'
This will match one or more spaces.
you can't do this using LIKE but what you can do, if you know this condition can exist in your data, is as you're inserting the data into the table, use regular expression matching to detect it up front and set a flag in a different column created for this purpose.
I just replace the whitespace chars with '%'. Lets say I want to do a LIKE query on a string like this 'I want to query this string with a LIKE'
#search_string = 'I want to query this string with a LIKE'
#search_string = ("%"+#search_string+"%").tr(" ", "%")
#my_query = MyTable.find(:all, :conditions => ['my_column LIKE ?', #search_string])
first I add the '%' to the start and end of string with
("%"+#search_string+"%")
and then replace other remaining whitespace chars with '%' like so
.tr(" ", "%")
http://www.techonthenet.com/sql/like.php
The patterns that you can choose from are:
% allows you to match any string of any length (including zero length)
_ allows you to match on a single character
I think that the question is not asking to match any spaces but to match two strings one a pattern and the other with wrong number of spaces because of typos.
In my case I have to check two fields from different tables one preloaded and the other filled typed by users so sometimes they don't respect 100% the pattern.
The solution was to use LIKE in the join
Select table1.field
from table1
left join table2 on table1.field like('%' + replace(table2.field,' ','%')+'%')
if the condition:
WHERE myField LIKE '%Hello world%'
doesn't work try
WHERE myField LIKE '%Hello%'
and
WHERE myField LIKE '%world%'
this approach is helpful in a few specific use cases, hope this helps.

Rightmost occurrence string match in MySQL

I would like to extract the file extension from a field in MySQL that contains filenames. This means I need to find the final '.' character in the field and extract everything after that. The following code example partially works:
SELECT LCASE(RIGHT(filename, LENGTH(filename) - LOCATE('.', filename)))
FROM mytable;
except that it falls down for cases where the file name contains more than one '.', where it extracts too much. In most programming languages I'd expect to find a function that gives me a rightmost match, but I can't find any such thing for MySQL, nor can I find any discussion from people who have had the same problem and found a workaround.
There is the substring_index function - it does exactly what you are looking for:
SELECT substring_index(filename, '.', -1) FROM mytable
Edit:
See Martin's answer, using substring_index(), with a negative count parameter is a MUCH better approach!
I'm downvoting myself (actually that's not possible...), upvoting Martin's answer; ' wish I could pass the accepted answer to him... Maybe OP will do that.
Original answer:
The following may do the trick (ATN: length may be off by 1, also may want to deal with case of filename value without a dot character.
SELECT LCASE(RIGHT(filename, LOCATE('.', REVERSE(filename) ) ))
FROM mytable;
Beware however that this type of post-facto parsing can be quite expensive (read slow), and you may consider extracting the file extension to a separate column, at load time.