Convert comma separated string into rows - sql

I have a comma separated string.
Now I'd like to separate this string value into each row.
Input:
1,2,3,4,5
Required output:
value
----------
1
2
3
4
5
How can I achieve this in sql?
Thanks in advance.

Use the STRING_SPLIT function if you are on SQL Server
SELECT value
FROM STRING_SPLIT('1,2,3,4,5', ',')
Else you can loop on the SUBSTRING_INDEX() function and insert every string in a temporary table.

If you are using Postgres, you can use string_to_array and unnest:
select *
from unnest(string_to_array('1,2,3,4,5',',') as t(value);

In Postgres, you can also use the 'regexp_split_to_table()' function.
If you're using MariaDB or MySQL you can use a recursive CTE such as:
with recursive itemtable as (
select
trim(substring_index(data, ',', 1)) as value,
right(data, length(data) - locate(',', data, 1)) as data
from (select '1,2,3,4,5' as data) as input
union
select
trim(substring_index(data, ',', 1)) as value,
right(data, length(data) - locate(',', data, 1)) as data
from itemtable
)

Related

Remove Substring according to specific pattern

I need to remove in a SQL Server database a substring according to a pattern:
Before: Winter_QZ6P91712017_115BPM
After: Winter_115BPM
Or
Before: cpx_Note In My Calendar_QZ6P91707044
After: cpx_Note In My Calendar
Basically delete the substring that has pattern _ + 12 chars.
I've tried PatIndex('_\S{12}', myCol) to get the index of the substring but it doesn't match anything.
Assuming you mean underscore followed by 12 characters that are not underscores you can use this pattern:
SELECT *,
CASE WHEN PATINDEX('%[_][^_][^_][^_][^_][^_][^_][^_][^_][^_][^_][^_][^_]%', str) > 0
THEN STUFF(str, PATINDEX('%[_][^_][^_][^_][^_][^_][^_][^_][^_][^_][^_][^_][^_]%', str), 13, '')
ELSE str
END
FROM (VALUES
('Winter_QZ6P91712017_115BPM'),
('Winter_115BPM_QZ6P91712017')
) AS tests(str)
late to the party, but you could also use latest STRING_SPLIT function to explode the string by underscores and count length of each segment between underscores. If the length is >=12, these sections must be replaced from original string via replace function recursively.
drop table if exists Tbl;
drop table if exists #temptable;
create table Tbl (input nvarchar(max));
insert into Tbl VALUES
('Winter_QZ6P91712017_115BPM'),
('cpx_Note In My Calendar_QZ6P91707044'),
('stuff_asdasd_QZ6P91712017'),
('stuff_asdasd_QZ6P91712017_stuff_asdasd_QZ6P91712017'),
('stuff_asdasd_QZ6P917120117_stuff_asdasd_QZ6P91712017');
select
input, value as replacethisstring,
rn = row_number() over (partition by input order by (select 1))
into #temptable
from
(
select
input,value as hyphensplit
from Tbl
cross apply string_split(input,'_')
)T cross apply string_split(hyphensplit,' ')
where len(value)>=12
; with cte as (
select input, inputtrans= replace(input,replacethisstring,''), level=1 from #temptable where rn=1
union all
select T.input,inputtrans=replace(cte.inputtrans,T.replacethisstring,''),level=level+1
from cte inner join #temptable T on T.input=cte.input and rn=level+1
--where level=rn
)
select input, inputtrans
from (
select *, rn=row_number() over (partition by input order by level desc) from cte
) T where rn=1
sample output
SQL Server doesn't support Regex. Considering, however, you just want to remove the first '_' and the 12 characters afterwards, you could use CHARINDEX to find the location of said underscore, and then STUFF to remove the 13 characters:
SELECT V.YourString,
STUFF(V.YourString, CHARINDEX('_',V.YourString),13,'') AS NewString
FROM (VALUES('Winter_QZ6P91712017_115BPM'))V(YourString);

How to combine return results of query in one row

I have a table that save personnel code.
When I select from this table I get 3 rows result such as:
2129,3394,3508,3534
2129,3508
4056
I want when create select result combine in one row such as:
2129,3394,3508,3534,2129,3508,4056
or distinct value such as:
2129,3394,3508,3534,4056
You should ideally avoid storing CSV data at all in your tables. That being said, for your first result set we can try using STRING_AGG:
SELECT STRING_AGG(col, ',') AS output
FROM yourTable;
Your second requirement is more tricky, and we can try going through a table to remove duplicates:
WITH cte AS (
SELECT DISTINCT VALUE AS col
FROM yourTable t
CROSS APPLY STRING_SPLIT(t.col, ',')
)
SELECT STRING_AGG(col, ',') WITHIN GROUP (ORDER BY CAST(col AS INT)) AS output
FROM cte;
Demo
I solved this by using STUFF and FOR XML PATH:
SELECT
STUFF((SELECT ',' + US.remain_uncompleted
FROM Table_request US
WHERE exclusive = 0 AND reqact = 1 AND reqend = 0
FOR XML PATH('')), 1, 1, '')
Thank you Tim

Select chunked data with row number using T-SQL

I have a SQL Server table containing a long text (varchar(max)) column and several key columns. I need to load this data into another table, but break the long text into chunks (varchar(4000)), so each row in the source table may become multiple rows in the target table.
Is there a way using T-SQL which can do this in one select statement and also provide a row_number? Sort of like partition over chunk size, if this makes sense.
Recursive CTE to split the string into 4000 character chunks (as a variation on this comma splitting thread: Turning a Comma Separated string into individual rows)
;WITH cte(SomeID, RowNum, DataItem, String) AS
(
SELECT
SomeID,
1,
LEFT(String, 4000),
case when len(String) > 4000 then
RIGHT(String, LEN(String) - 4000)
else
''
end
FROM myTable
UNION all
SELECT
SomeID,
RowNum + 1,
LEFT(String, 4000),
case when len(String) > 4000 then
RIGHT(String, LEN(String) - 4000)
else
''
end
FROM cte
WHERE
String > ''
)
SELECT *
FROM cte
You can use a recursive subquery:
with cte as (
select left(longtext, 4000) as val, 1 as rn,
stuff(longtext, 1, 4000, '') as rest
from t
union all
select left(rest, 4000), rn + 1,
stuff(longtext, 1, 4000, '') as rest
from cte
where longtext > ''
)
select *
from cte;
You probably want to include other columns as well, but your question doesn't mention them.
Also, if your text is really long (say more than a handful of chunks per row), then this is not going to be the most efficient method. There are related methods using recursive CTEs to solve this.

T-SQL function to split string with two delimiters as column separators into table

I'm looking for a t-sql function to get a string like:
a:b,c:d,e:f
and convert it to a table like
ID Value
a b
c d
e f
Anything I found in Internet incorporated single column parsing (e.g. XMLSplit function variations) but none of them letting me describe my string with two delimiters, one for column separation & the other for row separation.
Can you please guiding me regarding the issue? I have a very limited t-sql knowledge and cannot fork those read-made functions to get two column solution?
You can find a split() function on the web. Then, you can do string logic:
select left(val, charindex(':', val)) as col1,
substring(val, charindex(':', val) + 1, len(val)) as col2
from dbo.split(#str, ';') s(val);
You can use a custom SQL Split function in order to separate data-value columns
Here is a sql split function that you can use on a development system
It returns an ID value that can be helpful to keep id and value together
You need to split twice, first using "," then a second split using ";" character
declare #str nvarchar(100) = 'a:b,c:d,e:f'
select
id = max(id),
value = max(value)
from (
select
rowid,
id = case when id = 1 then val else null end,
value = case when id = 2 then val else null end
from (
select
s.id rowid, t.id, t.val
from (
select * from dbo.Split(#str, ',')
) s
cross apply dbo.Split(s.val, ':') t
) k
) m group by rowid

Split on colons in SQL Server

I have a column in SQL table which would have data like this:
"College: Queenstown College" or "University: University of Queensland"
Text before the ":" could be different. So, how can i select only the text before the ":" from the column and text after the ":(space)"?
You should probably consider putting your table into first normal form rather than storing 2 pieces of data in the same column...
;with yourtable as
(
select 'College: Queenstown College' as col UNION ALL
select 'University: University of Queensland'
)
select
left(col,charindex(': ',col)-1) AS InstitutionType,
substring(col, charindex(': ',col)+2, len(col)) AS InstitutionName
from yourtable
Using the charindex and substring functions:
substring(theField, 1, charindex(':', theField) - 1)