SQL Query replace string with placeholder - mysql

My table has lots of entries (image paths). Such a string is an URL and looks like that
https://example.com/images/do.php?id=1234
And i have to change them all to this format
https://example.com/images/1234.png
So the "ID" is equal to the filename. Replacing just the URL isn't that hard, but i have to add the static file extension, which is in my case "png" at the end of the URL string. So i need something like that
UPDATE post SET message = REPLACE(message, 'https://example.com/images/do.php?id=', 'https://example.com/images/{id}.png');
I'm absolutely no experienced SQL user, so can you please help me out?
Edit//
Now i have entries like that:
https://example.com/images/1234
https://example.com/images/5678
What is the query that i need to add the static file extension? So my entries looks like that:
https://example.com/images/1234.png
https://example.com/images/5678.png
The length of the ID's are between 4 to 6 characters. The main problem here why i can't just add the extension is, because my message row does contain more text than just the URL to modify. Such a row can look like that:
Here is your image link: [LINK]https://example.com/images/1234.png[/LINK] You can view it now.
Edit2//
My DB table named "post" does look as follows
id | message
----------------
1 | test
2 | Here is your image link: [LINK]https://example.com/images/1234[/LINK] You can view it now.
3 | some strings
4 | Here is your image link: [LINK]https://example.com/images/5678[/LINK] You can view it now.
5 | [LINK]no correct url[/LINK]
6 | [LINK][IMG]https://example.com/images/9123[/IMG][/LINK]
7 | [LINK]https://example.com/images/912364[/LINK]
So not every message row does contain an url and not every message with a [LINK]-tag does contain a proper url. Also there are enrties which have a longer ID, they should not be changed.

This answers the original version of the question.
This works for the example in your question:
select concat(substring_index(path, 'do.php', 1),
substring_index(path, '=', -1),
'.png')
from (select 'https://example.com/images/do.php?id=1234' as path) x
You can easily turn this to an update:
update post
set message = concat(substring_index(message, 'do.php', 1),
substring_index(message, '=', -1),
'.png')
where message like '%do.php%=%';

For your second problem:
UPDATE post
SET message = concat(message,'.png')
Just extend your current entry with '.png' :-)
EDIT: So, my bad! You should give Regex a try:
UPDATE post
SET message = CONCAT(REGEXP_SUBSTR(path,'.*https:\/\/example\.com\/images\/[0-9]{4,6}'),'.png',REGEXP_SUBSTR(path,'\[\/LINK\].*'))
This statement asserts that there is no file extension existing. So you can run the statement without where clause because the file extension won't get doubled.
For being sure you can check it before with:
SELECT
message
,CONCAT(REGEXP_SUBSTR(path,'.*https:\/\/example\.com\/images\/[0-9]{4,6}'),'.png',REGEXP_SUBSTR(path,'\[\/LINK\].*')) as corr_message
FROM path
Check the pattern as well on e.g. Regex101.com with your given example as string
Here is your image link: [LINK]https://example.com/images/1234[/LINK] You can view it now.
and the following as pattern
(.*https:\/\/example\.com\/images\/[0-9]{4,6})(\[\/LINK\].*)
The parenthesis builds groups. The first group is for the first part of the string. In update, this is the first Part of Concat. Afterwards we will set '.png'. The third part withing your update statement is represent with the second group of the regex-pattern.
Hope, this will help you. :)
EDIT2: Alright, this will fit to your rows.
UPDATE post
SET message = CONCAT(REGEXP_SUBSTR(path,'.*https:\/\/example\.com\/images\/[0-9]{4,6}'),'.png',REGEXP_SUBSTR(path,'\[\/(IMG|LINK)\].*'))
WHERE message LIKE '%https://example.com/images/%'
Pattern for checking it:
(.*https:\/\/example\.com\/images\/[0-9]{4,6})(\[\/(IMG|LINK)\].*)
As select for checking your data before update:
SELECT
message
,CONCAT(REGEXP_SUBSTR(path,'.*https:\/\/example\.com\/images\/[0-9]{4,6}'),'.png',REGEXP_SUBSTR(path,'\[\/(IMG|LINK)\].*')) as corr_message
FROM path
WHERE message LIKE '%https://example.com/images/%'
Hope this fits now for your case :)

Related

MySQL search and remove some text in a field

I have to update 2 fields in a table, assuming I have the following data:
Date CategoryID
2019-04-19 1,92,10
2019-04-18 4,105,10
2019-04-17 3,106,7,78
2019-04-16 3,108,10
I have to update CategoryID and remove the following category numbers if there is/are in row: 106, 107, 108 and 92
So the result will be:
Date CategoryID
2019-04-19 1,10
2019-04-18 4,105,10
2019-04-17 3,7,78
2019-04-16 3,10
Normally I use the REPLACE function, but in this case I don't know how to use it to remove that category and keep the others.
Could someone drive me?
Thank you, Lucas
EDIT: REGEXP_REPLACE from #Joakim Danielson did the trick. Thank you to all people who partecipate/reply, however, to all those who have criticized, this is not my code, it's Datalife Engine Blog :)
I use REGEXP_REPLACE with two similar patterns but with the comma , before and after to support the numbers being first, last or somewhere in the. middle
UPDATE test
SET categoryID = REGEXP_REPLACE(categoryID, '((106|107|108|92)([,]{1}))|(([,]{1})(106|107|108|92))', '')
This query is somewhat limited since it will replace both 106 and 1060 for instance. Is this a problem or is the id's limited in range so this is good enough?
Since I assume this is more of a one time thing you could divide it into 3 different updates to make sure you only get exact hits
-- id in the middle
UPDATE test
SET categoryID = REGEXP_REPLACE(categoryID, ',(106|107|108|92),', ',')
-- id at the start
UPDATE test
SET categoryID = REGEXP_REPLACE(categoryID, '^(106|107|108|92),', '')
-- id at the end
UPDATE test
SET categoryID = REGEXP_REPLACE(categoryID, ',(106|107|108|92)$', '')
you could use multiple replace calls, i.e. first run queries for for each number with a comma after it. I.e. this replaces 107, with empty string.
Then run queries for each number as single entry. I.e. replace 107 with empty string.
In both cases be aware of partial matches. So if you replace 97 with empty string it will also change id 197 to 1. Or when replacing 97, with empty string you might turn 197,4 into 14.
That is a horrible schema, at least for use in a relational database.
However, for getting what you asked for, see if this will work:
UPDATE thetable
SET CategoryID = "1,10"
WHERE Date = "2019-04-19"
To make this work, the sql query will have to be generated by a programming language which inspects strings and has some other way to figure out which row to update.
REGEXP_REPLACE from #Joakim Danielson did the trick. Thank you to all people who partecipate/reply, however, to all those who have criticized, this is not my code, it's Datalife Engine Blog :)

MySQL: Why aren't url's matching when using REPLACE?

My Situation:
I have url's in a field containing blog posts. The url's are being stored in my database with escape characters. My task at the moment is to replace some already inserted 'http' url's with 'https' url's, but REPLACE will match neither the original url nor the escaped url. I can't just replace every instance of 'http:', because I only want to affect certain links in each post, not every link.
I am very familiar with SQL, as well as REPLACE, so I'm not just asking how REPLACE works and how to use it. Another user here has tested my queries in his environment and they work. So, there must be something in my configuration that is preventing the queries from functioning as expected.
I have searched this site and google extensively for several hours and have found nothing specifically addressing my issue. Everything I have tried is included below and if there is something else I should try, I don't know what that is and I haven't found any suggestions/posts/comments that suggest doing anything differently.
Example URL:
http://test01.mysite.com
As Stored in DB:
http:\/\/test01.mysite.com
Code to Re-Create Situation:
DROP TABLE IF EXISTS test_posts;
CREATE TABLE IF NOT EXISTS test_posts (
id int NOT NULL AUTO_INCREMENT,
post_content longtext NOT NULL,
PRIMARY KEY (id)
)
INSERT INTO
test_posts
(post_content)
VALUES
('content content content Link I want to change content content content Link I don\'t want to change content content content Link I want to change content content content Link I don\'t want to change');
If I run
UPDATE
test_posts
SET
post_content = REPLACE(post_content, 'http://test01.mysite.com', 'https://test01.mysite.com');
or
UPDATE
test_posts
SET
post_content = REPLACE(post_content, 'http:\/\/test01.mysite.com', 'https://test01.mysite.com');
zero records are affected.
For testing purposes, I ran the following query which returns 0 rows.
SELECT
*
FROM
test_posts
WHERE
post_content LIKE '%http://test01.mysite.com%'
OR
post_content LIKE '%http:\/\/test01.mysite.com%'
OR
post_content LIKE '%http:\\/\\/test01.mysite.com%'
OR
post_content LIKE 'http:%/%/test01.mysite.com%';
If I run:
SELECT
*
FROM
test_posts
WHERE
post_content LIKE '%http:_/_/test01.mysite.com%'
It does return matches, but that doesn't solve the real problem of how to match when using UPDATE/REPLACE.
I have tried on two different servers and I get the same results on both.
I have tried the following Engine/Collation combinations and all return the same 0 records results:
MyISAM/latin1_swedish_ci
MyISAM/utf8mb4_unicode_ci
InnoDB/latin1_swedish_ci
InnoDB/utf8mb4_unicode_ci
Anybody know how I can write these queries so that REPLACE will find matches to those url's or what settings in my database or PhpMyAdmin may be causing the queries to return/affect 0 rows?
I think the backslash must be escaped in MySQL
field_name LIKE 'http:\\/\\/test01.mysite.com%'
Of course one could go for sure and use the single char wildcard __
field_name LIKE 'http:_/_/test01.mysite.com%'
or for your both cases: an optional backslash:
field_name LIKE 'http:%/%/test01.mysite.com%'
I'm still baffled as to why the queries with LIKE won't work, but, sadly, using those to narrow down the problem clouded my judgement and I didn't try all the same combinations in the REPLACE functions.
The following works:
UPDATE
test_posts
SET
post_content = REPLACE(post_content, 'http:\\/\\/test01.mysite.com', 'https://test01.mysite.com');
If anyone can explain to me why these combinations work with REPLACE, but not with LIKE, I'd really love to know. Thanks!
There is no reason, your query won't work if you have run properly, there is something else, you may be missing here.
UPDATE
test1
SET
name_1 = REPLACE(name_1, 'http:\/\/test01.mysite.com', 'https://test01.mysite.com')
works well and does the job of repalcing the \/ with /.
See screen-shot attached,
You may have some other problem, please check and update the question, if so.
Edit after comments
If you have more data points in URL, change query like below.
UPDATE
test1
SET
name_1 = REPLACE(name_1, '\/', '/')
Above will replace all the occurrence of \/ with /.
As \\ did not work to represent/escape a backslash, use regular expression functions:
REGEXP_LIKE('.*http:\\/\\/test01\.mysite.com.*')
REGEXP_REPLACE(field, 'http:\\/\\/', 'http://')
Here \\ should work.

JSON Queries - Failed to execute

So, I am trying to execute a query using ArcGIS API, but it should match any Json queries. I am kind of new to this query format, so I am pretty sure I must be missing something, but I can't figure out what it is.
This page allows for testing queries on the database before I actually implement them in my code. Features in this database have several fields, including OBJECTID and Identificatie. I would like to, for example, select the feature where Identificatie = 1. If I enter this in the Where field though (Identificatie = 1) an error Failed to execute appears. This happens for every field, except for OBJECTID. Querying where OBJECTID = 1 returns the correct results. I am obviously doing something wrong, but I don't get it why OBJECTID does work here. A brief explanation (or a link to a page documenting queries for JSON, which I haven't found), would be appreciated!
Identificatie, along with most other fields in the service you're using, is a string field. Therefore, you need to use single quotes in your WHERE clause:
Identificatie = '1'
Or to get one that actually exists:
Identificatie = '1714100000729432'
OBJECTID = 1 works without quotes because it's a numeric field.
Here's a link to the correct query. And here's a link to the query with all output fields included.

Zero padding : convert MD-1 to MD-001 with pure sql

guys I need help.
I am using Mysql / phpmyadim.
I have db with table which stores name and code id of people.
+--------+---------+
| Name | code_id |
+--------+---------+
| Nazeer | MD-1 |
+--------+---------+
I have 10 contacts and ids. I am using php program which used to generate automatic code.
recently i imported more records in to db from excel file and record increase to 5000+.
My php automatic code stopped generating codes giving me syntax error on code id.
I figured out that my excel import was having code id like MD-1, MD-2, etc. and my program used automatic code for number in 3 digits since my record is over thousands which 4 digit it give syntax error.
I did some research on solving that and the answer was to change all 2 digit numbers eg. "MD-1" ~ "MD-99" TO "MD-001" ~ "MD-099" and my program will work again.
so the question is how do i do that in phpmyadmin sql to change it. I need to keep 'MD-' and add '0' then add back the corresponding number.
thanks and appreciate your help in advance.
Regrds.
this sql will update all your data, but like I said in comments, you better off fixing your php code instead.
WARNING : this sql only works assuming all your data are in the format of [MD-xxx] with 3 or less numbers in it
UPDATE your_table SET
code_id=case length(substr(code_id,4))
WHEN 1 THEN concat("MD-00",substr(code_id,4))
WHEN 2 THEN concat("MD-0",substr(code_id,4))
ELSE code_id END;
I assume that you want to update the content MD-1 to MD-001 and MD-99 to MD-099. To do that you can write a PHP code to retrieve the rows one by one and have to match patterns and then update. Here are some useful links. link 1
HINT : you can check 5 digit string and then add another 0 in the position of 3.(use [exploid] to split by "-" and then concat with "-0" 2) There are no way to do the same only by using MYSQl since it's not a programming language. And other thing is PHP is not a program. It's a programming language.
run UPDATE query and use CONCAT function :
for ($x=0; $x=<upto>; $x++){
UPDATE <table_name>
SET <columnname>= CONCAT('MD-',0,$x)
WHERE <columnname>= CONCAT('MD-',$x)
}
Below simple update command can help you.
UPDATE mytable
SET code_id=IF(LENGTH(code_id)=4,CONCAT(SUBSTRING_INDEX(code_id,'-',1),'-00',SUBSTRING_INDEX(code_id,'-',-1)),IF(LENGTH(code_id)=5,CONCAT(SUBSTRING_INDEX(code_id,'-',1),'-0',SUBSTRING_INDEX(code_id,'-',-1)),code_id));

odd sql error, variable not being recognized correctly

I'm currently in hour two of this issue, I can't explain it so I will simply show what is going on. I don't know if this matters at all, but I am using the linkedIN API to retrieve a user's linkedIn unique ID.
In English, what I'm doing:
User Signs in with LinkedIn
I read-in user's LinkedIn ID (returned from the API)
If ID exists in database, say "hello", if not, show them a form to register
The issue I am having:
The following line works and properly returns the 1 user I have in the database with a linkedIn ID of OtOgMaJ2NM
$company_data = "SELECT * FROM s_user WHERE `LI_id` = 'OtOgMaJ2NM'";
The following query returns no results - using the same database with the same record in the table s_user:
$linkedIn_id = "<?js= id ?>";
echo $linkedIn_id;
The following code outputs OtOgMaJ2NM with no trailing spaces.
So far so good ... expcept when I run the query this time using the variable, no records are returned!
$company_data = "SELECT * FROM s_user WHERE `LI_id` = '$linkedIn_id'";
Further notes:
When I echo $company_data the same query is displayed when I use the variable as did when I used the plain text version of the query.
Anyone have ANY ideas?
Thanks,
Evan
I can only assume that when echoing variables it strips the tags, so when you're using it with the query you're actually saying:
$company_data = "SELECT * FROM s_user WHERE `LI_id` = '<?js= OtOgMaJ2NM ?>'";
I could be wrong, but have you tried stripping the tags from the variable?
If you send the variable between the "", the MySQL engine will search for $linkedIn_id literally and not for its content.
Seems you are using php, but I'm not sure about the right syntax. Take a look in the docs.