SQL Sub string Right char index - sql

input
-----------
'12345-123'
'3456-67'
output
-----------
column 1 column 2
12345 123
3456 67
In SQL For Column 1 :
SELECT Substring('12345-123',1,CHARINDEX('-','12345-123')-1)
For column 2 : unable to achieve ? can any one help me

a simple way to accomplish both columns using reverse(), keeps the logic identical.
SELECT Substring('12345-123',1,CHARINDEX('-','12345-123')-1) col1, reverse(Substring(reverse('12345-123'),1,CHARINDEX('-',reverse('12345-123'))-1)) col2

Well, you can use string manipulation:
select left(input, charindex('-', input) - 1) as col1,
stuff(input, 1, charindex('-', input), '') as col2
from t;
Here is a db<>fiddle.

Related

How to unpivot a single row in Oracle 11?

I have a row of data and I want to turn this row into a column so I can use a cursor to run through the data one by one. I have tried to use
SELECT * FROM TABLE(PIVOT(TEMPROW))
but I get
'PIVOT' Invalid Identifier error.
I have also tried that same syntax but with
('select * from TEMPROW')
Everything I see using pivot is always using count or sum but I just want this one single row of all varchar2 to turn into a column.
My row would look something like this:
ABC | 123 | aaa | bbb | 111 | 222 |
And I need it to turn into this:
ABC
123
aaa
bbb
111
222
My code is similar to this:
BEGIN
OPEN C_1 FOR SELECT * FROM TABLE(PIVOT( 'SELECT * FROM TEMPROW'));
LOOP
FETCH C_1 INTO TEMPDATA;
EXIT WHEN C_2%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(1);
END LOOP;
CLOSE C_1;
END;
You have to unpivot to convert whole row into 1 single column
select * from Table
UNPIVOT
(col for col in (
'ABC' , '123' , 'aaa' ,' bbb' , '111' , '222'
))
or use union but for that you need to add col names manually like
Select * from ( Select col1 from table
union
select col2 from table union...
Select coln from table)
sample output to show as below
One option for unpivoting would be numbering columns by decode() and cross join with the query containing the column numbers :
select decode(myId, 1, col1,
2, col2,
3, col3,
4, col4,
5, col5,
6, col6 ) as result_col
from temprow
cross join (select level AS myId FROM dual CONNECT BY level <= 6 );
or use a query with unpivot keyword by considering the common expression for the column ( namely col in this case ) must have same datatype as corresponding expression :
select result_col from
(
select col1, to_char(col2) as col2, col3, col4,
to_char(col5) as col5, to_char(col6) as col6
from temprow
)
unpivot (result_col for col in (col1,col2,col3,col4,col5,col6));
Demo

How to get everything after and before on a string in SQL Server

I have similar entries in my database:
Col1
---------
test\abcd\123\
test\abc\
test\abc\12\
test\abcdefg\1234\
I want to trim the string so I get: abcd or abc (middle part between the two backslashes)
I have tried this code, but it doesn't work (cuts too much)
SELECT SUBSTRING(col1, CHARINDEX('\',col1) + 1, CHARINDEX('\',col1,CHARINDEX('\',col1)) + 1)
I just need the middle part between the two backslashes.
You can extract the string between the first and the second backslashes as
with t(col1) as
(
select 'test\abc\123\' union all
select 'test\abc\' union all
select 'test\abc\12\' union all
select 'test\abcdefg\1234\'
)
select SUBSTRING(
col1,
CHARINDEX('\',col1)+1,
CHARINDEX('\',col1,CHARINDEX('\',col1)+1)-
CHARINDEX('\',col1)-1
)
from t;
Result String
-------------
abc
abc
abc
abcdefg
Demo
Edit (against probability of having col1 values with less than two backslashes use):
select SUBSTRING(
col1,
CHARINDEX('\',col1)+1,
CHARINDEX('\',col1,CHARINDEX('\',col1)+1)-
CHARINDEX('\',col1)-1
)
from t
where len(col1) - len(replace(col1,'\','')) >= 2
to filter completely them away.
or
select case when len(col1) - len(replace(col1,'\','')) >= 2 then
SUBSTRING(
col1,
CHARINDEX('\',col1)+1,
CHARINDEX('\',col1,CHARINDEX('\',col1)+1)-
CHARINDEX('\',col1)-1
)
else
col1
end
as "Result String"
from t
display all rows, leave the ones as the same spoiling the rule.

How to find each case of matching pattern within a string and return as rows

I'm trying to identify reference numbers contained in strings in a column. The table looks something like this:
col1 col2
1 fgREF1234fhjdREF1235hgkjREF1236
2 hREF1237hjdfREF1238djhfhs
Need to write an SQL query that identifies the 'REF' followed by the 4 digits and returns each in its own row.
The output should look like this:
col1 ref
1 REF1234
1 REF1235
1 REF1236
2 REF1237
2 REF1238
I have tried:
select
case when substr(substr(col2, instr(col2, 'REF'), 7), 1, 1) like 'R'
then substr(col2, instr(col2, 'R'), 7) else null end ref
from table
...but this will only identify the first match in the string.
I am using Oracle SQL but ideally the solution would be able to be converted to other SQL variants.
Any help would be much appreciated!
You can use regexp_substr delimited by connect by level <= regexp_count(col2,'REF') ( the appearance time of the pattern string REF within the strings col2 )
with t(col1,col2) as
(
select 1,'fgREF1234fhjdREF1235hgkjREF1236' from dual union all
select 2,'hREF1237hjdfREF1238djhfhs' from dual
)
select col1,
regexp_substr(col2,'REF[0-9]+',1,level) as ref
from t
connect by level <= regexp_count(col2,'REF')
and prior col1 = col1
and prior sys_guid() is not null;
Demo
You can use the below code to get the desired result :-
select x.col1, explode(x.ref) as ref from (
select col1,split(trim(regexp_replace(col2,'[^REF0-9]',' ')),' ') as ref
from inp

SQL Server Convert Particular Column Values into comma separated String

I have a table in Database as below :
Id Name
1 Item1
1 Item2
2 Item3
1 Item4
3 Item5
I need output as below(3rd column is count):
1 Item1,Item2,Item4 3
2 Item3 1
3 Item5 1
How it can achieved by SQL Query ?
SQL Server has STUFF() function which could able to help you.
SELECT t.Id,
Name = STUFF( (SELECT DISTINCT ','+Name
FROM table
WHERE Id = t.Id
FOR XML PATH('')
), 1, 1, ''
)
FROM table t
GROUP BY t.Id;
SQL Server 2017 has introduced a much easier way to achieve this using STRING_AGG(expression, separator).
Here's an example:
SELECT STRING_AGG(T.Name, ', ') FROM MyTable T where MyColumnID = 78
You could even play around with formatting in other ways like this one:
SELECT STRING_AGG(CONCAT(T.MyColumnID,' - ',T.Name), ', ') FROM MyTable T where MyColumnID = 78
More info in this blog I found about it: https://database.guide/the-sql-server-equivalent-to-group_concat/
select id, group_concat(name) csv,
from Table
group by id

How to split column value in Oracle sql

How to split a column value which is not having space or any other delimiter. I searched the forums but I couldn't able to find the solution for my scenario.
Here is my scenario
ID Column_Value
011 abcdefgh
The result should be
Column_Value1 Column_Value2
abcd efgh
Assuming you just want to split a column down the middle, you can achieve this with a combination of substr and length:
SELECT SUBSTR(column_value, 1, LENGTH(column_value) / 2),
SUBSTR(column_value, LENGTH(column_value) / 2 + 1)
FROM mytable
SQLFiddle
If you want to split the string based on the length and number of characters, then use SUBSTR as follows:
SQL> with data(str) as(
2 select 'abcdefgh' from dual
3 )
4 select substr(str, 1, 4) col1,
5 substr(str, length(substr(str, 1, 4)) +1) col2
6 from data;
COL1 COL2
---- ----
abcd efgh
SQL>
Above, you could change the value of 4 to your desired value. Remember, both are not mutually exclusive.