extract part of string before and after substr - mysql

I have a DB column like this .. part_1/part_2?part_3
Of course I've tried SUBSTRING_INDEX but it does not return the central part of the string.
I want to select records that match part_2. How do I do that?

Instead of using SUBSTRING_INDEX, use this : SUBSTRING(str, pos, len)
str is the column,
pos is the position where you want to start the substring and
len is the length of the substring.
Check out this link for more on this.
You could try something like :
SELECT
SUBSTRING_INDEX(SUBSTRING(COLUMN_NAME,5), '?', 1) AS PART2
FROM TABLE_NAME

Related

SQL: Substring until second character starting from right keeping left values

I have this filename AAAA_BBBBB_CC_HDDD_HGGG.csv and I'm trying to keep the values after the second underscore starting from the right.
So i want to keep any values just before _HDDD_HGGG.csv
This is my code:
SET #NFileN = REVERSE(SUBSTRING(REVERSE(#source_filename),1,CHARINDEX('_',REVERSE(#source_filename), CHARINDEX('_', REVERSE (#source_filename), 0) + 1)))
And this is the returned value:
(6 rows affected)
_HDDD_HGGG.csv
Instead of being AAAA_BBBBB_CC.
Does anyone has a clue for this?
You are taking a SUBSTRING from 1 till your CHARINDEX while your string is reversed. Either reverse your string again or use LEN to find the length of your string like so:
REVERSE(
SUBSTRING(
REVERSE(#source_filename),
CHARINDEX('_',
REVERSE(#source_filename),
CHARINDEX('_',
REVERSE (#source_filename),
0)+1)+1,
LEN(#source_filename)
)
)
p.s.: Added a second +1 to remove the "_" between CC and HDDD
p.p.s: CHARINDEX is a SQL Server function which I assume is what you are actually using. The MySQL equivalent would be POSITION, the equivalent for LEN would be LENGTH

substring_index skips delimiter from right

I have a table 'car_purchases' with a 'description' column. The column is a string that includes first name initial followed by full stop, space and last name.
An example of the Description column is
'Car purchased by J. Blow'
I am using 'substring_index' function to extract the letter preceding the '.' in the column string. Like so:
SELECT
Description,
SUBSTRING_INDEX(Description, '.', 1) as TrimInitial,
SUBSTRING_INDEX(
SUBSTRING_INDEX(Description, '.', 1),' ', -1) as trimmed,
length(SUBSTRING_INDEX(
SUBSTRING_INDEX(Description, '.', 1),' ', -1)) as length
from car_purchases;
I will call this query 1.
picture of the result set (Result 1) is as follows
As you can see the problem is that the 'trimmed' column in the select statement starts counting the 2nd delimiter ' ' instead of the first from the right and produces the result 'by J' instead of just 'J'. Further the length column indicates that the string length is 5 instead of 4 so WTF?
However when I perform the following select statement;
select SUBSTRING_INDEX(
SUBSTRING_INDEX('Car purchased by J. Blow', '.', 1),' ', -1); -- query 2
Result = 'J' as 'Result 2'.
As you can see from result 1 the string in column 'Description' is exactly (as far as I can tell) the same as the string from 'Result 2'. But when the substring_index is performed on the column (instead of just the string itself) the result ignores the first delimiter and selects a string from the 2nd delimiter from the right of the string.
I've racked my brains over this and have tried 'by ' and ' by' as delimiters but both options do not produce the desired result of a single character. I do not want to add further complexity to query 1 by using a trim function. I've also tried the cast function on result column 'trimmed' but still no success. I do not want to concat it either.
There is an anomaly in the 'length' column of query 1 where if I change the length function to char_length function like so:
select length(SUBSTRING_INDEX(
SUBSTRING_INDEX(Description, '.', 1),' ', -1)) as length -- result = 5
select char_length(SUBSTRING_INDEX(
SUBSTRING_INDEX(Description, '.', 1),' ', -1)) as length -- result = 4
Can anyone please explain to me why the above select statement would produce 2 different results? I think this is the reason why I am not getting my desired result.
But just to be clear my desired outcome is to get 'J' not 'by J'.
I guess I could try reverse but I dont think this is an acceptable compromise. Also I am not familiar with collation and charset principles except that I just use the defaults.
Cheers Players!!!!
CHAR_LENGTH returns length in characters, so a string with 4 2-byte characters would return 4. LENGTH however returns length in bytes, so a string with 4 2-byte characters would return 8. The discrepancy in your results (including SUBSTRING_INDEX) says that the "space" between by and J is not actually a single-byte space (ASCII 0x20) but a 2-byte character that looks like a space. To workaround this, you could try replacing all unicode characters with spaces using CONVERT and REPLACE. In this example, I have an en-space unicode character in the string between by and J. The CONVERT changes that to a ?, and the REPLACE then converts that to a space:
SELECT SUBSTRING_INDEX( SUBSTRING_INDEX("Car purchased by J. Blow", '.', 1),' ', -1)
Output:
by J
With CONVERT and REPLACE:
SELECT SUBSTRING_INDEX( SUBSTRING_INDEX(REPLACE(CONVERT("Car purchased by J. Blow" USING ASCII), '?', ' '), '.', 1),' ', -1)
Output
J
For your query, you would replace the string with your column name i.e.
SELECT SUBSTRING_INDEX( SUBSTRING_INDEX(REPLACE(CONVERT(description USING ASCII), '?', ' '), '.', 1),' ', -1)
Demo on DBFiddle

How to replace only few characters from a string in mysql?

I have a field urn_sem.studentid that I'd like to replace a few characters in; for example:
ABC/2011/BCOMH_NC/I/12 → ABC/2011/BCOMH/I/12
ABC/2011/BCOMH_NC/I/24 → ABC/2011/BCOMH/I/24
I've tried this query:
SELECT REPLACE(studentid, 'KNC/2011/BCOMH_NC/', ' KNC/2011/BCOMH/')
FROM urn_sem
but it doesn't show the new value.
Do you want this:
update urn_sem
set studentid = REPLACE(studentid, 'KNC/2011/BCOMH_NC/', ' KNC/2011/BCOMH/')
where studentid like '%KNC/2011/BCOMH_NC/%'
The WHERE clause is optional. It ensures that the replace is only on rows that change.
And this sample query does not work?
SELECT REPLACE (studentid, '_', '') FROM urn_sem

MySQL : left part of a string split by a separator string?

I need a MySQL function to get the left part of a string with variable length, before the separator.
For example, with separator string '==' :
abcdef==12345 should return abcdef
abcdefgh==12 should return abcdefgh
Also the same thing, but for the right part...
SELECT SUBSTRING_INDEX(column_name, '==', 1) FROM table ; // for left
SELECT SUBSTRING_INDEX(column_name, '==', -1) FROM table; // for right
select substring_index('abcdef==12345','==',1)
for the right part use -1 instead of 1.
I would look into the substring function in SQL which is SUBSTR, but it is more for set positions in the string, not so much for variable lengths.
http://www.1keydata.com/sql/sql-substring.html

MySQL query to replace spaces in a column with underscores

I have a MySQL database table 'photos' with a column 'filename'.
I need to replace the spaces in the filename column values with underscores.
Is it possible with a single/multiple query? If so how?
You can use the REPLACE function :
REPLACE(str,from_str,to_str)
Returns the string str with all
occurrences of the string from_str
replaced by the string to_str.
REPLACE() performs a case-sensitive
match when searching for from_str.
So, to replace all occurences of a character by another one in all lines of a table, something like this should do :
update photos set filename = replace(filename, ' ', '_');
ie, you search for ' ' in the column filename and use '_' instead ; and put the result back into filename.
update photos set filename = replace(filename,' ', '_');