MySql Regexp result word part of known word - mysql

Been struggling for this for awhile.
Is there a way to find all rows in my table where the word in the column 'word' is a part of a search word?
+---------+-----------------+
| id_word | word |
+---------+-----------------+
| 177041 | utvälj |
| 119270 | fonders |
| 39968 | flamländarens |
| 63567 | hänvisningarnas |
| 61244 | hovdansers |
+---------+-----------------+
I want to extract the row 119270, fonders. I want to do this by passing in the word 'plafonders'.
SELECT * FROM words WHERE word REGEXP 'plafonders$'
That query will of course not work in this case, would've been perfect if it had been the other way around.
Does anyone know a solution to this?

SELECT * FROM words WHERE 'plafonders' REGEXP concat(word, '$')
should accomplish what you want. Your regex:
plafonders$
is looking for plafonders at the end of the column. This is looking for everything the column has until its end, e.g. the regexp is fonders$ for 119270.
See https://regex101.com/r/Ytb3kg/1/ compared to https://regex101.com/r/Ytb3kg/2/.

MySQL's REGEXP does not handle accented letters very well. Perhaps it will work OK in your limited situation.
Here's a slightly faster approach (though it still requires a table scan):
SELECT * FROM words
WHERE 'PLAutvälj' =
RIGHT('PLAutvälj', CHAR_LENGTH(word)) = word;
(To check the accents, I picked a different word from your table.)

Related

MySQL - Special characters in column value

I got a big data (approximately 600,000).
I want the rows with value "word's" will appear.
Special characters will be completely ignored.
TABLE:
| column_value |
| ------------- |
| word's |
| hello |
| world |
QUERY: select * from table where column_value like '%words%'
RESULTS:
| column_value |
| ------------- |
| word's |
I want the rows with special characters will appear and ignore their special characters.
Can you please help me how can we achieve it with fast runtime?
You can use replace to remove the "special" character prior the matching.
SELECT *
FROM table
WHERE replace(column_value, '''', '') LIKE '%words%';
Nest the replace() calls for other characters.
Or you try it with regular expressions.
SELECT *
FROM table
WHERE column_value REGEXP 'w[^a-zA-Z]*o[^a-zA-Z]*r[^a-zA-Z]*d[^a-zA-Z]*s';
[^a-zA-Z]* matches optional characters, that are not a, ..., y and z and not A, ..., Y and Z, so this matches your search word also with any non alphas between the letters.
Or you have a look at the options full text search brings with it. Maybe that can help too.
You must add an index on your column_value.
MySQL doc

mysql - search for the exact word phrase without using regex nor rlike

I have my table like this:
|name |
-----------------
|Joseph Jackson |
|Aiden Chase |
|Luke Benjamin |
|Joseph |
|Joseph2 |
If I search for the word Joseph (SELECT * from myTable where name="Joseph" ) I woud get only the last result:
|name |
-----------------
|Joseph |
If I search for the word Jackson, I won't get any results.
That is what I DON'T want.
What I want is to get the records that exist in the exact word searched, for example:
if the word searched is Joseph, I woud get:
|name |
-----------------
|Joseph |
|Joseph Jackson |
*Notice that Joseph2 is not in the result set.
If the word searched is Jackson, I woud get:
|name |
-----------------
|Joseph Jackson |
*But I cannot use like '%Jose%' (the use of like) cuz I will get Joseph2 and I want the exact word(Jose).
*If the word searched is Jose for example I shouldn't get any result, cuz Jose is not in the data (also I shouldn't get records that contain the Joseph word).
The only way I've found is using regex for example:
SELECT * from myTable where REGEXP [[:<:]]Joseph[[:>:]]
|name |
-----------------
|Joseph |
|Joseph Jackson |
SELECT * from myTable where REGEXP [[:<:]]Jackson[[:>:]]
|name |
-----------------
|Joseph Jackson |
I want this results but without using regex and whithout rlike, is there any way? How? thanks.
This screams for FULLTEXT search
ALTER TABLE T ADD FULLTEXT INDEX (name);
SELECT * FROM T WHERE MATCH (name) AGAINST ('+Joseph' IN BOOLEAN MODE);
FIDDLE
Although full text as #Mihai suggests is definitely the way to go for production, if you want to do a one-off search without building extra indices you can just use LIKE by adding spaces around the names and search for the name including surrounding spaces;
SELECT * FROM myTable
WHERE CONCAT(' ', name, ' ') LIKE CONCAT('% ', 'joseph', ' %')
Note that this will definitely not use any indexes, so can be useful for admin purposes but not for a production application that cannot handle full table scans.
allow your stored procedure to accept a parameter for #name then you can use the WHERE clause
WHERE name = #name

SELECTing (almost) duplicate rows

My table looks something like this:
| id (int) | sentence (varchar) |
I want to find all rows that are almost the same except for one particular word. Eg:
| 230 | test |
| 321 | test sth |
...
| 329 | is (sth) it?
| 923 | is it?
The word that can be different is sth in this case. Ideally I could use some sort of "array" with the list of words that can be different.
Is this something I could do purely in SQL?
Just an untested quick shot, sorry, but I think you could do something like
SELECT * FROM table GROUP BY REPLACE(text, 'sth', '')
You can use SOUNDEX. So with the examples that you gave, these queries:
SELECT SOUNDEX('test')
SELECT SOUNDEX('test sth')
SELECT SOUNDEX('is (sth) it?')
SELECT SOUNDEX('is it?')
return these results:
T230
T230
I200
I200
That means that the first two and the second two sound like each other. What I can't be sure of is how well this will work with your actual data, you're just going to have to try it.

How to match hyphen delimited in any order

I need to match a set of characters delimited by a hyphen - for example:
B-B/w-W/Br-W-Br
Where the / are part of what I need, up to 20 spaces.
G-R-B, G/R-B-B/W-O
So I need a regex that covers between the -'s in any order (G-R-B could also be R-B-G)
I've been playing around with a bunch of combo's, but I can't come up with something that will match any order.
The plan is to search this way using mysql. So, it'll be something like
select * from table1 where pinout REGEXP '';
I just can't get the regex right :/
Description
This expression will match the string providing each of the hyphen delimited values are included in the string. The color values can appear in the string in any order so this expression will match W/Br-b-B/w and B/w-W/Br-b... or any other combinations which include those colors.
^ # match the start to of the string
(?=.*?(?:^|-)W\/Br(?=-|$)) # require the string to have a w/br
(?=.*?(?:^|-)b(?=-|$)) # require the string to have a b
(?=.*?(?:^|-)B\/w(?=-|$)) # require the string to have a b/w
.* # match the entire string
MySql doesn't really support the look arounds so this will need to be broken into a group of where statements
mysql> SELECT * FROM dog WHERE ( color REGEXP '.*(^|-)W\/Br(-|$)' and color REGEXP '.*(^|-)b(-|$)' and color REGEXP '.*(^|-)B\/w(-|$)' );
+-------+--------+---------+------+------------+---------------------+
| name | owner | species | sex | birth | color |
+-------+--------+---------+------+------------+---------------------+
| Claws | Gwen | cat | m | 1994-03-17 | B-B/w-W/Br-W-Br |
| Buffy | Harold | dog | f | 1989-05-13 | G-R-B, G/R-B-B/W-O |
+-------+--------+---------+------+------------+---------------------+
See also this working sqlfiddle: http://sqlfiddle.com/#!2/943af/1/0
Using a regex in conjunction with a MySql where statement can be found here: http://dev.mysql.com/doc/refman/5.1/en/pattern-matching.html
I might have misunderstood from your example, try this:
-*([a-zA-Z/]+)-*
The capture region can be altered to include your specific letters of interest, e.g. [GRBWOgrbwo/].
Edit: I don't think this will help you in the context you're using it, but I'll leave it here for posterity.

MySQL Natural Sort (like OSX Finder)

I've searched for this for a long time, but the solutions I've found aren't working as I need.
Let me explain: I have a table containing a couple of thousands of products, each one with an alphanumeric SKU, used also for sorting.
This SKU consists of:
Category Code (variable number of alphabetic characters),
Product Number (integer),
Product Model Variation (optional, variable number of alphabetic characters)
For example: MANT 12 CL (without spaces)
Now, I need to get them ordered like this (and if these were filenames, OSX Finder would order them perfectly):
MANT1
MANT2
MANT2C
MANT2D
MANT2W
MANT3
MANT4C
MANT9
MANT12
MANT12C
MANT12CL
MANT12P
MANT13
MANT21
MANT24
MANT24D
MANT29
Of course ORDER BY sku is plainly wrong:
MANT1
MANT12
MANT12C
MANT12CL
MANT12P
MANT13
MANT2
MANT21
MANT24
MANT24D
MANT29
MANT2C
MANT2D
MANT2W
MANT3
MANT4C
MANT9
And ORDER BY LENGTH(sku), sku has problems sorting the model variations:
MANT1
MANT2
MANT3
MANT9
MANT12
MANT13
MANT21
MANT24
MANT29
MANT2C
MANT2D
MANT2W
MANT4C
MANT12C
MANT12P
MANT24D
MANT12CL
So, is there a way to sort this stuff like Finder would?
(Also, once sorted, is there a way to get the next and previous product? I don't mind using several queries: at this point elegance is the last of my problems...)
Thanks everybody in advance.
One last thing: during my searches I've found this answer to a similar question
but I have no idea how to use it in PHP, so I don't know if it works and is actually an answer to my question.
Are you using PHP when fetching data?
If so, try using natural sort function for in memory sort after data is already loaded?
The order is not 'plain wrong', it simply depends what collation you use. In your case, you might try the binary collation, for example, 'latin1_bin'.
Following example the ORDER BY using COLLATE for UTF8 data:
mysql> SELECT c1 FROM t1 ORDER BY c1;
+------+
| c1 |
+------+
| a1 |
| a12 |
| a13c |
| a2 |
| a21 |
+------+
mysql> SELECT c1 FROM t1 ORDER BY c1 COLLATE 'utf8_bin';
+------+
| c1 |
+------+
| a1 |
| a12 |
| a2 |
| a21 |
| a13c |
+------+