mysql regular replace characters with empty char - mysql

I have the following strings in the table:
step1.cards.choice_step_1
step1.cards.choice_step_2
step2.cards.choice_step_1
step2.cards.choice_step_2
I would replace with empty characters all in these string using that pattern:
^step([0-9]|[1-9][0-9]).cards.choice_step_1$
^step([0-9]|[1-9][0-9]).cards.choice_step_2$
Does it possible to do that in MySQL?
Finally I would have in result:
1
1
2
2
EDIT
select regex_replace('[^0-9]','','step1.cards.choice_step_1');
return me
11
please help on correct pattern on the following data :
sometext.step1
sometext.step1.cards.choice_step_1
sometext.step1.cards.choice_step_2
sometext.step1.desire
sometext.step2
sometext.step2.cards.choice_step_1
sometext.step2.cards.choice_step_2
sometext.step2.desire
to get the following result:
step1
step1
step1
step1
step2
step2
step2
step2

You could try something like this:
create table test (field1 varchar(100));
select * from test;
+------------------------------------+
| field1 |
+------------------------------------+
| sometext.step1 |
| sometext.step1.cards.choice_step_1 |
| sometext.step1.cards.choice_step_2 |
| sometext.step1.desire |
| sometext.step2 |
| sometext.step2.cards.choice_step_1 |
| sometext.step2.cards.choice_step_2 |
| sometext.step2.desire |
| step1 |
+------------------------------------+
Query:
select
field1,
-- find position of step
position('step' in field1) as step,
-- find position of dot AFTER step is found
position('.' in
substr(field1, position('step' in field1), length(field1)))
+ position('step' in field1) as dot,
-- if position of 'step' --and-- position of 'step' + position of 'dot' is 1
-- that means: step is at position 1 and dot is not found, display field as is
-- if position of 'step' --and-- position of 'step' + position of 'dot' are equal
-- that means: dot is not found. Grab everything from step onwards
-- if position of 'step' --and-- position of 'step' + position of 'dot' are **NOT** equal
-- grab everything from where step was found thruogh just before dot was found
case
when position('step' in field1) = 1
and
position('.' in substr(field1, position('step' in field1), length(field1)))
+ position('step' in field1) = 1
then
field1
when position('step' in field1) =
position('.' in substr(field1, position('step' in field1), length(field1)))
+ position('step' in field1)
then
substr(field1, position('step' in field1), length(field1))
else
substr(field1,
position('step' in field1),
position('.' in substr(field1, position('step' in field1), length(field1)))-1
)
end as ans
from test;
Result:
+------------------------------------+------+------+-------+
| field1 | step | dot | ans |
+------------------------------------+------+------+-------+
| sometext.step1 | 10 | 10 | step1 |
| sometext.step1.cards.choice_step_1 | 10 | 16 | step1 |
| sometext.step1.cards.choice_step_2 | 10 | 16 | step1 |
| sometext.step1.desire | 10 | 16 | step1 |
| sometext.step2 | 10 | 10 | step2 |
| sometext.step2.cards.choice_step_1 | 10 | 16 | step2 |
| sometext.step2.cards.choice_step_2 | 10 | 16 | step2 |
| sometext.step2.desire | 10 | 16 | step2 |
| step1 | 1 | 1 | step1 |
+------------------------------------+------+------+-------+
Notice the last field that has the data you desire. Please feel free to tweak this to your needs.

Related

Find the max value in the last digit

I am using MySQL 5.5. I am facing a problem on how to find the max value in the last digit.
For example below the table, I want to get the max value is detected the last digit. The result should be 100-1-15
Table name: abc
+----+------------+
| id | code |
+----+------------+
| 1 | 100-1-1 |
| 2 | 100-1-2 |
| 3 | 100-1-15 |
| 4 | 100-1-6 |
| 5 | 100-1-3 |
| 6 | 100-1-5 |
| 7 | 100-1-9 |
+----+------------+
I am using below the SQL query, but doesn't work:
SELECT id,max(code) FROM abc;
Hope someone can guide me how to solve it and can get the max code is 100-1-15. Thanks.
SELECT *
from abc
order by SUBSTRING_INDEX(code, '-', -1) + 0 desc
limit 1
Try
Select
id,
code
from abc
order by max(CAST(SUBSTR(code, 7, LENGTH(code)-6) AS SIGNED))
limit 1;

How to remove the special character from any length of the string in MYSQL

I have sample Data
+----+-----------+
| Id | Name |
+----+-----------+
| 1 | $John |
| 2 | $Carol |
| 3 | $Mike |
| 4 | $Sam |
| 5 | $David$Mohan$ |
6 | $David$
7 | $David$Mohan$
| 8 | Robert$Ram$ |
| 9 | Maxwell$ |
+----+-----------+
I need to remove the only $ first character
Need output :
+----+-----------+
| Id | Name |
+----+-----------+
| 1 | John |
| 2 | Carol |
| 3 | Mike |
| 4 | Sam |
| 5 | David$Mohan |
6 | David
7 | David$Mohan
| 8 | Robert$Ram |
| 9 | Maxwell |
+----+-----------+
Select REPLACE(col,'$','') from Tbl
select regexp_replace(name, '^$', '') name from mytable
I have tried with Replace and Substring but still missing the point .
Can anyone suggest me .
If you are only looking for starting $, you can use this below logic-
DEMO HERE
SELECT
CASE
WHEN LEFT(D,1) = '$' THEN RIGHT(D, LENGTH(D)-1)
ELSE D
END STR,
IF(LEFT(D,1) = '$', RIGHT(D, LENGTH(D)-1), D) STR2
-- you can use any of the above option
FROM
(
select '$David$Mohan$' D UNION ALL
select 'Da$Mo$'
)A
Try this:
select
id,
case when SUBSTR(Name, 1,1)='$' and SUBSTR(Name,-1,1)='$' then substr(Name,2,(length(Name)-2))
when SUBSTR(Name, 1,1)='$' then substr(Name,2)
else Name
end
from Tbl
Based on your example you should try;
Replace(trim(replace({col},'$',' ')), ' ','$')
This is turning the '$' into spaces, removing spaces at the start or end or the string, then switching back to '$'.
Try this, it's working for me for all your test cases
SELECT REGEXP_SUBSTR(name,'[^$].+[^$]') from users;
If case you want to replace $ with space, David$Ang => David Ang
SELECT REGEXP_REPLACE(REGEXP_SUBSTR(name,'[^$].+[^$]'), "[$]", " ") from users;

Need to Separate the String with a separator of - in MYSQL

I have this string 1111-2222-3-4-55-12345678901234567 1 in MYSQL Table Field.
What I need to do is to separate first 5 parameters separated with a -. Like I need to Separate:
1111
2222
3
4
55
$stringElements = explode('-', $string);
echo $stringElements[0];// 1111
echo $stringElements[1];// 2222
echo $stringElements[2];// 3
echo $stringElements[3];// 4
echo $stringElements[4];// 55
$stringElements[5];// 12345678901234567 1
Even though I did not test it, this should solve your problem.
SELECT `mystring`,
SUBSTRING_INDEX(mystring,'-',1) AS part1,
SUBSTRING_INDEX(SUBSTRING_INDEX(mystring,'-',2),'-',-1) AS part2,
SUBSTRING_INDEX(SUBSTRING_INDEX(mystring,'-',3),'-',-1) AS part3,
SUBSTRING_INDEX(SUBSTRING_INDEX(mystring,'-',4),'-',-1) AS part4,
SUBSTRING_INDEX(SUBSTRING_INDEX(mystring,'-',5),'-',-1) AS part5,
FROM my_table;
------------------------------------------------------------------------------
| mystring | part1 | part2 | part3 | part4 | part5 |
------------------------------------------------------------------------------
| 1111-2222-3-4-55-12345678901234567 | 1111 | 2222 | 3 | 4 | 55 |
This is splitting the text with an increased index count and re-splitting it from the last index for each part through part2 to part5
If the length of each section within the string is constant, then
select replace(left(fieldname,16),'-','') as alias from table
will do the trick.
UPDATE:
If you need to have each individual value in a separate field, then it's a slightly more complicated:
SELECT REPLACE(SUBSTRING(SUBSTRING_INDEX(fieldname, '-', 1), LENGTH(SUBSTRING_INDEX(fieldname,'-', 0)) + 1) as first,
REPLACE(SUBSTRING(SUBSTRING_INDEX(fieldname, '-', 2), LENGTH(SUBSTRING_INDEX(fieldname,'-', 1)) + 1) as second,
...
FROM table
You can create function:
CREATE FUNCTION SPLIT_STR(
x VARCHAR(255),
delim VARCHAR(12),
pos INT
)
RETURNS VARCHAR(255)
RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos),
LENGTH(SUBSTRING_INDEX(x, delim, pos -1)) + 1),
delim, '');
and then use it like
SELECT SPLIT_STR('1-2-3', '-', 1);
it will return 1. With all this examples you can easily build your own query
Source: http://blog.fedecarg.com/2009/02/22/mysql-split-string-function/
SELECT * FROM ints;
+---+
| i |
+---+
| 0 |
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
+---+
SELECT DISTINCT SUBSTRING_INDEX(SUBSTRING_INDEX('1111-2222-3-4-55-12345678901234567','-',i+1),'-',-1) x FROM ints;
+-------------------+
| x |
+-------------------+
| 1111 |
| 2222 |
| 3 |
| 4 |
| 55 |
| 12345678901234567 |
+-------------------+

Issue with UNION in MySQL

I have two tables.
rp_format
+-----+--+--------------+
| fid | | recordformat |
+-----+--+--------------+
| 1 | | CD |
| 2 | | Vinyl |
| 3 | | DVD |
+-----+--+--------------+
rp_records
+----+--+--------+
| id | | format |
+----+--+--------+
| 1 | | 1 |
| 2 | | 2 |
| 3 | | 3 |
+----+--+--------+
What I would like to achieve is to display everything from "rp_format". But I would also like make a check to see if there is a "fid"-value found in "format".
Example that should be displayed on page like this:
fid recordformat
1 CD Remove this format
2 Vinyl Remove this format
3 DVD Remove this format
But let's say an "fid" value is found in "format" then I would like it to be displayed like this on page:
fid recordformat
1 CD Remove this format
2 Vinyl Can't remove this format
3 DVD Remove this format
"Remove this format / Can't remove this format" is text that will be displayed by checking if "fid" = "format" using PHP.
Here is my SQL query so far:
global $wpdb;
$rpdb = $wpdb->prefix . 'rp_format';
$rpdb2 = $wpdb->prefix . 'rp_records';
$sql = "
SELECT *
FROM $rpdb
LEFT OUTER JOIN $rpdb2 ON $rpdb.fid = $rpdb2.format
UNION
SELECT *
FROM $rpdb
RIGHT OUTER JOIN $rpdb2 ON $rpdb.fid = $rpdb2.format
WHERE $rpdb.fid IS NOT NULL
";
The issue I have with this query is that when "fid" is found in "format" (let's say it's found 10 times) every of these 10 values will be outputed also.
How can this be fixed?
Kind regards
Johan
If I understand correctly you want to display some message depending on if the data exists on rp_records or not and avoid multiple display.
Consider the following
mysql> select * from rp_format;
+------+--------------+
| fid | recordformat |
+------+--------------+
| 1 | CD |
| 2 | Vinyl |
| 3 | DVD |
| 4 | Test |
+------+--------------+
4 rows in set (0.00 sec)
mysql> select * from rp_records;
+------+--------+
| id | format |
+------+--------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 2 |
| 5 | 1 |
+------+--------+
So the query is
select
f.*,
case
when r.format is not null then 'Can\'t remove' else 'Remove this' end
as message
from rp_format f
left join rp_records r on r.format = f.fid
group by f.fid ;
+------+--------------+--------------+
| fid | recordformat | message |
+------+--------------+--------------+
| 1 | CD | Can't remove |
| 2 | Vinyl | Can't remove |
| 3 | DVD | Can't remove |
| 4 | Test | Remove this |
+------+--------------+--------------+
Not sure that i correctly understand your logic with found and not found format, if i wrong - add to if condition r.format IS NOT NULL instead r.format IS NULL. And i think you no need to use union, you should use join:
SELECT
r.fid,
f.recordformat,
IF(r.format IS NULL, "Can't remove this format", "Remove this format")
FROM rp_format f
LEFT JOIN rp_records r ON f.fid = r.format
GROUP BY f.fid
;
I'm sure that something like this will help you!

SQL Query in Ruby: Only select the changes

Suppose I have a table (PriceHistory) like this, every time I change anything in the row, I will record the whole row again in the table.
id | buy_price | sell_price | change_date
1 | 2 | 2 | 2012-06-22
2 | 3 | 2 | 2012-06-20
3 | 2 | 6 | 2012-06-15
4 | 5 | 5 | 2012-06-15
5 | 5 | 7 | 2012-06-15
6 | 4 | 8 | 2012-06-12
I only care about the change of BuyPrice, Is there a way to just select row 1, 2, 3, & 5?
Here is the Ruby code I come up with, but it does not only select the changed rows
PriceHistory.select("id, BuyPrice, change_date").
order("change_date DESC")
Both Ruby and SQL answers are fine.
Try this:
#histories = PriceHistory.select("id, BuyPrice, change_date").order("change_date DESC")
(#histories.size - 1).times do |n|
if #histories[n].buy_price != #histories[n+1].buy_price
puts "changed from : " + #histories[n].id.to_s + " to: " + #histories[n+1].id.to_s
end
end
Good luck!