Substring regex matching in mysql - mysql

I've one complex question that been struggle me for couple hours and seeking help from mysql expert. :)
Thank you in advanced.
Table : t1 ; Column: name
Given table:
name
-----
$abc|def|$cde
efd|$acd
$gcb|$bvv|ggg
Expected outcome (pull only the string without $ prefix, pipe indicates the field values separator):
name
-----
def
efd
ggg
-- Sql to create and insert
create table t1 (name varchar(100));
insert into t1 (name) values ('$abc|def|$cde');
insert into t1 (name) values ('efd|$acd');
insert into t1 (name) values ('$gcb|$bvv|ggg');
Mysql version: 5.6.40

SELECT DISTINCT
name, SUBSTRING_INDEX(SUBSTRING_INDEX(t1.name, '|', num), '|', -1) one_value
FROM t1
/* max 3 subnames per name - expand if needed */
CROSS JOIN (SELECT 1 num UNION SELECT 2 UNION SELECT 3) numbers
HAVING one_value NOT LIKE '$%';
fiddle

On MySQL 8+, you could try:
SELECT
col,
REGEXP_REPLACE(CONCAT('|', col, '|'), '^.*\\|([a-z]+)\\|.*$', '$1') AS col_out
FROM yourTable;
The idea here is to start with this slightly modified column value:
|$abc|def|$cde|
Then, we search for a letter-only sequence surrounded by pipes, and replace with that captured group.
Demo

Related

How to SQL select excluding strings with N duplicate characters in a row

How to make a select from a table excluding rows with N duplicate characters in a row in a certain column? Let's say N=5
'0000011114BR13471' // Exclude
'554XXXXXXXXXXXXXX' // Exclude
'000111114BR134716' // Exclude
'000011114BR134716' // Include
'11880000000000000' // Exclude
'12345678901200000' // Exclude
'12345678901200001' // Include
I tried many combinations but none of them worked. For example:
SELECT * FROM mytable WHERE not (mycolumn regexp '(.)\1{5,}');
Thank you!
You can use the LIKE to match regular Expression and EXCEPT clause to exclude unwanted Results. A query like this might work
In SQL SERVER
Select * from myTable
EXCEPT
Select * from myTable WHERE ColumnName like '(.)\1{4,}'
In MySQl
Select * from myTable
where ColumnName Not In(
Select ColumnName from myTable WHERE ColumnName RLIKE '(.)\1{4,}')
Here N=5. the 4 in regular expration represents 5 duplicates.
I don't think MySQL supports back-references in regular expressions -- which is a shame for your problem. One method is brute force:
select t.*
from t
where col not regexp '0{5}|1{5}|2{5}|3{5}|4{5}|5{5}|6{5}|7{5}|8{5}|9{5}|X{5}';
Another method is a recursive CTE, which breaks up the string into individual characters and then uses window functions to determine if there are 5 in a row:
with recursive cte as (
select col,left(col, 1) as chr, substr(col, 2) as rest, 1 as lev
from t
union all
select col, left(rest, 1), substr(rest, 2), lev + 1
from cte
where rest <> ''
)
select col
from (select cte.*,
lead(lev, 4) over (partition by col, chr order by lev) as chr_4
from cte
) x
group by col
having max(chr_4 = lev + 4) = 0
Here is a db<>fiddle.
In MySQL 8.0:
mycolumn regexp '(.)\\1{4}'
Notes:
Two backslashes are needed.
Since there is 1 selected (.), you need to check for only 4 more, not 5.
The , (meaning "or more") is unnecessary.

How to sort the string on the basis of numbers?

I am working on the sql query in which I want to sort the string on the basis of numbers.
I have one column (Column Name is Name) table in which there are multiple fields. On using ORDER BY NAME, it prints in the following way:
hello_world
hello_world10
hello_world11
hello_world12
hello_world13
hello_world14
hello_world15
hello_world4
hello_world5
For the above query, I have used ORDER BY NAME; but it doesn't seem to print on the basis of numbers.
Problem Statement:
I am wondering what sql query I need to write or what changes I need to make in my sql query above so that it prints everything on the basis of numbers, the o/p should be this:
hello_world
hello_world4
hello_world5
hello_world10
hello_world11
hello_world12
hello_world13
hello_world14
hello_world15
you want a numeric ordering, then you need to create a numeric value to order on.
currently you have strings.
if the pattern is true, then you can use a combination of string manipulation to trim off the first characters, which should leave only numbers, then use TO_NUMBER() to convert for the ordering
something like
select name
from mytable
order by to_number( replace( name, 'hello_world','' ))
I think the simplest solution for this particular case (where all the values have the same prefix) is:
order by length(name), name
Try this:
SELECT name,
CASE WHEN REGEXP_INSTR(name, '[0-9]') = 0 THEN 0
ELSE CAST(SUBSTR(name, REGEXP_INSTR(name, '[0-9]')) AS INT)
END AS progressive
FROM my_table
ORDER BY progressive;
we can order it using replace and cast methods.
I tried the following query
select Name, cast(REPLACE(Name, 'hello_world', '') as UNSIGNED ) as repl from Users order by repl;
To generage sample data
CREATE TABLE Users (
Name varchar(255) NOT NULL
);
insert into Users(Name) values
('hello_world'),
('hello_world4'),
('hello_world5'),
('hello_world10'),
('hello_world11'),
('hello_world12'),
('hello_world13'),
('hello_world14'),
('hello_world15')
;
EDIT
query without replaced column,
select City from Persons order by cast(REPLACE(City, 'hello_world', '') as UNSIGNED );
Though the question is about mysql.
I tried in sql server.
create table #t1 (id varchar(100));
insert into #t1 (id) values ('Pq1'),('pq3'),('pq2')
select * from #t
order by
CAST(SUBSTRING(id + '0', PATINDEX('%[0-9]%', id + '0'), LEN(id + '0')) AS INT)

SQL Help | The select list for the INSERT statement contains fewer items than the insert list

Please see my query below,
insert into dbo.orderDetails(orderNo,clientId,productId,quantity)
values(' ee941422-5546-4d62-b5d6-60ecd13ca2b8 ')
select client_id,product_id,amount from dbo.cart
where client_id =' efc08f7c-fdfc-4712-9488-fc1c55acb95e ' ;
In this I want a static orderno and the rest should come from the a table(dbo.cart).when i execute my query its shows this error
There are more columns in the INSERT statement than values specified in the
VALUES clause. The number of values in the VALUES clause must match the
number of columns specified in the INSERT statement.
Any solution.
You can't have both VALUES and SELECT. If you want to insert static values, put it into the SELECT list.
insert into dbo.orderDetails(orderNo,clientId,productId,quantity)
select ' ee941422-5546-4d62-b5d6-60ecd13ca2b8 ', client_id,product_id,amount from dbo.cart
where client_id =' efc08f7c-fdfc-4712-9488-fc1c55acb95e ' ;
My issue has been resolved, Below is the query which is working for me
INSERT INTO Exam_Trigger(Questions,CAT_ID,TOPIC_ID,SCHEDULED_TYPE,UPDATE_USER,UPDATE_DT,CREATE_USER,CREATE_DT)
select id ,'2','2','Weekly','',curdate(),'',curdate() from ( select GROUP_CONCAT(id SEPARATOR ',')as id from(select id from question_data order by rand() limit 4)as ls) as ps

MySQL How to split string from column by " " and insert result separated by , into another column?

I would like to ask how to split string from column (all rows in table) by " " and insert result separated by , into another column in same table?
Many thanks for any advice.
Table struct example:
------------------------------------------
| Original string | Spliced string |
------------------------------------------
| Some string 001 | Some,String,001 |
------------------------------------------
If I needed to "split" a string on a delimiter, I'd likely make use of the nifty SUBSTRING_INDEX function. But there are a few quirks to be aware of.
The approach I would take would certainly be to write a SELECT statement first. That would include the expression(s) in the SELECT list that return the "separated" values that I wanted to assign to another column. I'd get those expressions tested using a SELECT statement, before I wrote an UPDATE statement.
SELECT t.id
, t.column_i_want_to_split
, expr1
FROM mytable t
ORDER BY t.id
To test specific cases, I'd make use of an inline view
SELECT t.id
, t.note
, t.val
, expr1
FROM ( SELECT 1 AS id, 'empty string test' AS note, '' AS val
UNION ALL SELECT 2, 'null', NULL
UNION ALL SELECT 3, 'one space', ' '
UNION ALL SELECT 4, 'four spaces', ' '
UNION ALL SELECT 5, 'test5', ' abc def '
UNION ALL SELECT 6, 'test6', 'g hi kl m'
) t
ORDER BY t.id
Once I had the expression(s) returning the values I want to assign to another column, I'd convert the SELECT into an UPDATE statement. To process all rows, omit the WHERE clause.
UPDATE mytable t
SET t.another_column = expr1
Without a more definitive specification, or at least some concrete examples of what you are attempting to achieve, we're just guessing. Given only a general description of the problem, all we can offer is some general advice.

MySQL: Using variable on a WHERE IN clause

I'm becoming mad trying to use an "array" of values obtained from a GROUP_CONCAT into a WHERE IN statement, when GROUP_CONCAT only takes one "id" it works ok but when it takes more it doesn't.
As it follows:
START TRANSACTION;
DECLARE #coupon_ids VARCHAR(MAX);
-- Take one or more ids
SET #coupon_ids:=(SELECT IFNULL( (SELECT GROUP_CONCAT(coupon_id) FROM some_table WHERE order_id=(SELECT entity_id FROM sales_order WHERE increment_id=310033638) GROUP BY order_id), (SELECT coupon_id FROM some_table WHERE coupon_id=310033638)));
SELECT #coupon_ids;
INSERT INTO some_table_gift VALUES (NULL,TRIM('whatever'),'','');
SET #lastid:=LAST_INSERT_ID();
-- Here if #coupon_ids is just one id, like 123 it works, if it is a list of them like 123,234,254 it doesn't works
UPDATE some_table SET owner_id=#lastid,is_gift=1 WHERE coupon_id IN (#coupon_ids);
COMMIT;
-- Same here
SELECT coupon_id,owner_id,is_gift FROM some_table WHERE coupon_id IN (#coupon_ids);
Does anyone know how to work with this?
Thanks!
What's your filed type for coupon_id, if it is not any number type than it will not work.
One way you can add quote (single quote) for each result in GROUP_CONCAT Write
GROUP_CONCAT(coupon_id SEPARATOR '","')
remove SELECT #coupon_ids
And
in QUERY try this WHERE coupon_id IN ("#coupon_ids")