MS SQL Query to remove prefixes - mysql

I have below like column values and would like to exclude the characters as well as the hyphen and only return digits. The replace function is not entirely helpful as sometimes the character length is 3 and sometimes its 4, see below as the digit length changes as well.
abc-1234567
sdfr-9876540
try-12345678
case-098765

If you want the part after the last hyphen, you can use substring_index():
select substring_index(col, '-', -1)
You can also extract the digits at the end using regexp_substr():
select regexp_substr(col, '[0-9]+$')

Related

SELECT/LOCATE Query Outputting Incorrect Results

I have a column (kills) with values separated by colons as such: 0;2;0. I wanted to select whatever the middle digit may be, and came up with this query:
SELECT RIGHT(kills, LOCATE(';', kills) - 1)-LEFT(kills, LOCATE(';', kills) - 1) FROM stats WHERE id='135' AND LOCATE(';', kills) > 0;
(I'm aware the where clause is specific, it was for debug purposes. It would realistically be set to a variable which outputs the row id)
It works perfectly fine when the results all have the same decimal place such as 1;2;3 or 10;20;30, but returns wild results when the case is otherwise, such as 1;20;30 or 10;20;3.
1;20;21 outputs 0. -- 10;20;2 outputs -10.
2;20;21 outputs -1. -- 20;20;2 outputs -20.
9;20;21 outputs -8. -- 90;20;2 outputs -90.
I would like to select the middle value of all of these values even if one value doesn't share the same decimal place.
If you want the middle number of three, then you want the second number. Use substring_index():
select substring_index(substring_index(kills, ';', 2), ';', -1)

mysql remove last characters is character if its number

From select statement, in a filed I want to remove last characters is character if its number. Is there string function available in MySQL?
for these two SQL I want
test
as output
select 'test1';
select 'test';
Another way is to use REGEXP,
SET #val = 'test12';
SELECT CONCAT(LEFT(#val, CHAR_LENGTH(#val) - 1),
IF(RIGHT(#val, 1) REGEXP '[0-9]' = 0, RIGHT(#val, 1), ''))
SQLFiddle Demo
SQLFiddle Demo (another example)
To remove the last character if it's numeric, one way to do this without using a regular expression is with LEFT, RIGHT and LENGTH :
select if( right(yourfield,1) = 0 && right(yourfield,1) != '0',
yourfield,
left(yourfield, length(yourfield) - 1))
from yourtable;
To replace all trailing numeric values, you can use REVERSE:
select if( cast(reverse(yourfield) as signed) = 0 && right(yourfield,1) != '0',
yourfield,
left(yourfield, length(yourfield) - length((reverse(yourfield) + 0))))
from yourtable;
SQL Fiddle Demo
When casting fields as integers/signed in MySQL, it will cast all the numeric characters up to the first non-numeric character -- thus making the REVERSE work. If the last character is not numeric, it results in 0.
Using the IF check above, if the last character isn't numeric, then it prints the original value, else it prints all but the last character.
here is a pointer:
use a union between two queries.
in the first - either use REGEX, or grab the substr of the field where another substr for the last char is a number,
then union the text field where the substr of the last char is not a number.
You might want to use Regular Expressions inside MySQL. This package might help you https://launchpad.net/mysql-udf-regexp. However, I do not recommend to do it inside MySQL statement as it might be slow. You would better to do it after grabbing the value inside your programming language.

How to order by a part of a column

i have field with content like this: 1, 2, 100 first two numbers can be any size third one can be up to 100.
Now i need to sort my fields by this third number but since i have 2 other numbers i don't know how to do it.
Maybe i could use something like REGEXP or something else?
So far i've tried SUBSTRING but since my two numbers can be any lenght something like
order by SUBSTRING(my_field, 4)
would work but if i have numbers like 32, 451, 30 it takes wrong numbers
Also i use php for to build my query, but i don't think it matters.
You can use SUBSTRING_INDEX. So something like:
SUBSTRING_INDEX(my_field, ',', -1)
EDIT: if you have spaces you might want to do some trimming as well.
ORDER BY SUBSTRING_INDEX(my_field,',',-1)+0 ASC -- or DESC
Use SUBSTRING_INDEX, which grabs the substring up to the nth occurence of the delimiter (in your case, comma), or, in the case of a negative n, it will return the substring after the nth occurence from the end.
To see what I mean try:
SELECT SUBSTRING_INDEX(my_field,',',-1)
FROM my_table
The reason there is a +0 in the ORDER BY is so that mysql sorts these as numbers, not strings.
This should work:
order by CONVERT(SUBSTRING(my_field, LOCATE(",", my_field, RIGHT)), INTEGER)
SELECT *
FROM (
SELECT
SUBSTRING(my_field, 4) AS my_field,
...
FROM
...
WHERE
...
) temp_table
ORDER BY my_field

MySQL replace numbers after hyphen

I have a large table with ZIP codes but they are in long format like : 06608-1405
What I require is to REMOVE the hyphen and the numbers after the hyphen. I have using MYSQL REPLACE before but not sure how if you can use Wildcards.
Cheers for you time.
J
How about using SUBSTRING_INDEX:
select SUBSTRING_INDEX(ZIP, '-', 1);
Edit:
To update the table:
Update <table-name> set ZIP = SUBSTRING_INDEX(ZIP, '-', 1);
If the numbers before the hypen are all the same length (5), you can do SUBSTRING(zip, 0, 5)
Or even SUBSTRING(zip, 0, LOCATE('-', zip))
Or LEFT(zip, LOCATE('-', zip)) if you wanna follow the other suggestion that was made.
If they're all ZIP codes (i.e., 5 digits, hyphen, 4 digits), you can just use:
mysql> SELECT LEFT(table.zip_code, 5); // (06608-1405 -> 06608)
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_left
use a combination of the left() the instr() functions
http://dev.mysql.com/doc/refman/5.1/en/string-functions.html
i.e.
select left('12345-6789', instr('12345-6789', '-') - 1)
returns
12345
(could/should be refined to only carry out left() operation if instr() returns a non-zero value).
EDIT: to remove the hyphen etc. use:
update my_table
set my_col = left(my_col, instr(my_col, '-') - 1)

Selecting X words from a text field in MySQL

I'm building a basic search functionality, using LIKE (I'd be using fulltext but can't at the moment) and I'm wondering if MySQL can, on searching for a keyword (e.g. WHERE field LIKE '%word%') return 20 words either side of the keyword, as well?
You can do it all in the query using SUBSTRING_INDEX
CONCAT_WS(
' ',
-- 20 words before
TRIM(
SUBSTRING_INDEX(
SUBSTRING(field, 1, INSTR(field, 'word') - 1 ),
' ',
-20
)
),
-- your word
'word',
-- 20 words after
TRIM(
SUBSTRING_INDEX(
SUBSTRING(field, INSTR(field, 'word') + LENGTH('word') ),
' ',
20
)
)
)
Use the INSTR() function to find the position of the word in the string, and then use SUBSTRING() function to select a portion of characters before and after the position.
You'd have to look out that your SUBSTRING instruction don't use negative values or you'll get weird results.
Try that, and report back.
I don't think its possible to limit the number of words returned, however to limit the number of chars returned you could do something like
SELECT SUBSTRING(field_name, LOCATE('keyword', field_name) - chars_before, total_chars) FROM table_name WHERE field_name LIKE "%keyword%"
chars_before - is the number of
chars you wish to select before the
keyword(s)
total_chars - is the
total number of chars you wish to
select
i.e. the following example would return 30 chars of data staring from 15 chars before the keyword
SUBSTRING(field_name, LOCATE('keyword', field_name) - 15, 30)
Note: as aryeh pointed out, any negative values in SUBSTRING() buggers things up considerably - for example if the keyword is found within the first [chars_before] chars of the field, then the last [chars_before] chars of data in the field are returned.
I think your best bet is to get the result via SQL query and apply a regular expression programatically that will allow you to retrieve a group of words before and after the searched word.
I can't test it now, but the regular expression should be something like:
.*(\w+)\s*WORD\s*(\w+).*
where you replace WORD for the searched word and use regex group 1 as before-words, and 2 as after-words
I will test it later when I can ask my RegexBuddy if it will work :) and I will post it here