looking for REGEXP_REPLACE() alternative on MySQL 5.7.27 - mysql

I made a query on one of the projects i m working on (On MariaDB 10.1.37):
SELECT * FROM table WHERE REGEXP_REPLACE(substring_index(product,' ',1), '[^a-zA-Z ]', '')='VALUE'
Where goal was:
1) from value select part till first space: example VALUE1 SOME OTHER to get VALUE1
2) to remove numbers and any other symbol: example VALUE1 to get VALUE
And query above does the trick as needed!
Issue is that on client side there is MySQL 5.7.27 and as we know REGEXP_REPLACE() came in MySQL on 8+ version
For now there are no options to upgrade client side to MySQL 8+ or migrate to MariaBD so the question is how and can i achieve the same result in MySQL 5.7.27?
I tried to search and tried WHERE substring_index(product,' ',1) REGEXP '^a-zA-Z' = 'VALUE' but REGEXP returns 1 or 0 and it is not what works for me as i need value. …
Any help?
Thanks in advance!

'Been searching for a solution as well since my mates are on MYSQL 5.5 and therefore they don't have REGEXP_REPLACE() either.
It's easy to find the solution on stackOverFlow for replacing just one char, but couldn't find for a string, therefore I've created that piece of code, it could help someone :
SET #string = 'I love shop it is a terrific shop, I love eveything about it';
SET #shop_code = 'shop';
SET #shop_date = CONCAT(#shop_code, '__', DATE_FORMAT(NOW(), '%Y_%m_%d__%Hh%im%ss'));
SET #part1 = SUBSTRING_INDEX(#string, #shop_code, 1);
SET #shop_nb = ROUND( (LENGTH(#string) - LENGTH(REPLACE(#string, #shop_code,''))) / LENGTH(#shop_code) );
SET #part2 = SUBSTRING_INDEX(#string, #shop_code, -#shop_nb);
SET #string = CONCAT(#part1, #shop_date, #part2);
SELECT #string;

This is not a final answer and if someone have a good or closer example to what i have asked then go ahead and post an answer. I would like to see it!
What i did is i just used LIKE
SELECT * FROM table WHERE substring_index(product,' ',1) LIKE 'VALUE%'
I know that this can show wrong data for some case but for my needs this way is acceptable.

This works in MySQL 5.7... This example would be extracting a UTM_Source parameter value from a URL's query string:
case when url like '%utm_source%' then
substring(
url,
locate('utm_source=',url)+char_length('utm_source='),
case when locate('&',url,locate('utm_source=',url)) = 0 then char_length(url)+1 else locate('&',url,locate('utm_source=',url)) end - (locate('utm_source=',url)+char_length('utm_source='))
) else NULL end utm_source;

Related

MySQL SUBSTR LOCATE multi-search-strings

Tricky one, and my brain is mush after staring at my screen for about an hour.
I'm trying to query my database to return the first part of a string (domain name eg. http://www.example.com) in the column image_link.
I have managed this for all rows where the image_link contains .com as part of the string... but I need the code to be more versatile, so it searches for the likes of .net and .co.uk too.
Had thought some sort of nested REPLACE might work, but it doesn't make sense when I try to apply it - and I'm stuck.
Query Builder code:
$builder->select("SUBSTRING(image_link, 1, LOCATE('.com', image_link) + 3) AS domain");
Example strings, with desired results:
http://www.example.com/brands/567.jpg // http://www.example.com
https://www.example.org/photo.png // https://www.example.org
http://example.net/789 // http://example.net
Any help/advice warmly welcomed!
SELECT ... ,
SUBSTRING_INDEX(image_link, '/', 3) domain
FROM test;
Or, if protocol may be absent, then
SELECT ... ,
SUBSTRING_INDEX(image_link, '/', CASE WHEN LOCATE('//', image_link) THEN 3 ELSE 1 END) domain
FROM test;
fiddle

Mysql Query Request

Straight to the point and this might be very simple for some of you.
I have a simple SELECT query (select description from table) which produces all i want like below :
- testword123
- testword875
- myjob1 45
- myjob is 544
What i need is to have as a result :
- testword
- myjob
I can use a SELECT distinct LEFT(description,8) which works fine, but the problem is not ALL 'description' have the same number of words :-(
So basically, what i want is retrieve ONLY the letters from the 'description' result set.
Thanks!!
R
SELECT distinct LEFT(description, charindex(' ', description) - 1)
Depending on your implementation, it might be possible to declare 'description' as a variable beforehand so you don't have to type it twice in the same query.
There are two decisions:
1) Handle each decription in PHP
or
2) Handle user input before writing it to DB. Add field to table as index of first not letter symbol and then use it in LEFT mysql function
Thanks "undefined_variable" - Your solution "stackoverflow.com/questions/11134452/…; was the correct one!! (y) (with a little bit of tweaking, this helped A LOT) A+++

In Postgresql, how I tell a trigger Function to... IF NOT FOUND do nothing (pass)

Im creating Trigger FUnctions with PostgreSQL 9.1, how I tell it in this Trigger Function...
IF NEW.timetype = 'start' THEN
SELECT timestmp FROM tbl_ebscb_saaaa_log WHERE fnname = NEW.fnname AND timetype = 'start' ORDER BY stmtserial DESC LIMIT 1 INTO v_timestmp_start;
IF FOUND THEN
NEW.timetypespan := age(NEW.timestpm, v_timestmp_start);
ELSE
END IF;
I would like to... IF NOT FOUND then do nothing (like "pass" in python), what do I do? just leave it in blank??? Is not inside any loop.
Thanks Advanced.
PD: please if some could provide a good link with examples about basic postgresql work flow. Thanks Again.
There are at least two ways to do this in SQL generally:
First way is to not retrieve the value, but just check it. This would replace your select statement with an if exists statement. Use this method if you don't need to do anything else with the v_timestmp_start value.
It would look like: IF EXISTS (SELECT 1 FROM tbl WHERE ...) THEN ....
The other way would be to check the value of the variable which should be NULL if the select did not find anything. This would look very much like what you already have (but replace found with IF NOT NULL).
This would look like: IF v_timestmp_start IS NOT NULL THEN ....
And one more option that is unique to postgres. This looks exactly like what you already have (IF FOUND THEN ...).

HTML Entity decoding to Special characters

I want to display special symbols in my output.
For eg: My text may contain entity codes like <, > etc.
I want to display this as <, > in my output. I need to do this in SQL.
I googled about this and got a function,
select dbms_xmlgen.convert('ABC <; ',0) from dual
This does the reverse process, it generates the output as 'ABC <'
I tried with decoding but it does not work. I even changed the sql command as,
select dbms_xmlgen.convert('ABC <; ',1) from dual, where 1 is for entity_decode, but I don't get the desired output.
Instead of using DBMS_XMLGEN.convert, I used the function UTL_I18N.UNESCAPE_REFERENCE:
SELECT UTL_I18N.UNESCAPE_REFERENCE('ABC < ') FROM DUAL;
result:
ABC <
More information on the Oracle doc: http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/u_i18n.htm#i998992
Try something like:
SELECT DBMS_XMLGEN.CONVERT('ABC < ', DBMS_XMLGEN.ENTITY_DECODE) FROM DUAL
Also, see the Oracle docs for that.
EDIT:
Ok, so apparently this is a bug in some Oracle versions (9.2.0.1 and 10.1.0.2, as it seems). Somebody solved it by wrapping the function. I don't know how that's supposed to solve it, but it my be worth trying. Create a function like this:
CREATE OR REPLACE FUNCTION
xml_decode(
i_xml_string IN VARCHAR2
)
RETURN VARCHAR2
IS
BEGIN
RETURN
DBMS_XMLGEN.convert(
i_xml_string,
DBMS_XMLGEN.ENTITY_DECODE
);
END;
And use it instead:
SELECT xml_decode('ABC < ') FROM DUAL;
Let us know if that works.

MySQL "in" command

I want to know how we can do this using the IN comparison syntax.
The current SQL query is :
select * from employee
where (employeeName = 'AJAY' and month(empMonth) = month(curdate()))
or (employeeName ='VINAY' and month(empMonth) = month(curdate()))
I tried it using IN comparison function, but am unable to properly set the pieces. Can any one help me?
select * from employee
where employeeName in ('AJAY','VINAY')
and month(empMonth) = month(curdate()); // ERROR.
I tried it in MySQL Query.
Thank You,
Sindhu
Your solution is fine for most DBMS (data-base management systems). As far as I know it is no problem in MySQL. But some years ago I had similar problems in DB2 and also in another more exotic DBMS named "Focus".
Maybe this can help:
Put the complete where-block into a pair of brackets.
Inside this block put each comparison in a pair of brackets again.
Move the IN-Comparison to the end of the where-block.
This would transform your example into this code:
SELECT *
FROM employee
WHERE (
(month(empMonth) = month(curdate())
AND
(employeeName IN ('AJAY','VINAY'))
);