Sql query to create single row to multiple row [duplicate] - sql

This question already has answers here:
Turning a Comma Separated string into individual rows
(16 answers)
Closed 8 years ago.
I have a table as given below
ID Value
----- ----------
1 10,20,30
I need the result as
ID Value
--- -------
1 10
1 20
1 30
Thanks.

This will work
;with tmp(Id, value, Data) as (
select Id, LEFT(value, CHARINDEX(',',value+',')-1),
STUFF(value, 1, CHARINDEX(',',value+','), '')
from #Testdata
union all
select Id, LEFT(Data, CHARINDEX(',',Data+',')-1),
STUFF(Data, 1, CHARINDEX(',',Data+','), '')
from tmp
where Data > ''
)
select Id, value
from tmp
order by Id
Possible duplicate Turning a Comma Separated string into individual rows

Please try the following:
SELECT A.ID,
Split.a.value('.', 'VARCHAR(100)') AS Value
FROM (SELECT ID,
CAST ('<V>' + REPLACE(Value, ',', '</V><V>') + '</V>' AS XML) AS Value
FROM YourTable
) AS A
CROSS APPLY Value.nodes ('/V') AS Split(a);

Related

SQL row values to one column [duplicate]

This question already has answers here:
How to concatenate text from multiple rows into a single text string in SQL Server
(47 answers)
Closed 2 years ago.
I have a SQL query which return the below data;
I need to write Values to one row depend ID and Code column like below;
SELECT ID, Code, STRING_AGG(Value) AS Value
FROM dbo.Table
GROUP BY ID, Code;
Considering you're using up to date version.
Please check below attempt. There are other options also you can use.
SELECT
CAST(408 AS INT) AS ID,
CAST(1 AS INT) AS CODE,
CAST('A' AS VARCHAR(20)) AS VALUE
INTO
#tmpgroupby
INSERT INTO #tmpgroupby
VALUES
(408,1,'B'),
(408,1,'C'),
(408,1,'D'),
(408,1,'E'),
(408,1,'F'),
(408,1,'G'),
(408,2,'H'),
(408,2,'I'),
(408,2,'J'),
(408,2,'K')
SELECT ID,CODE, STUFF(
(SELECT ', ' + convert(varchar(10), t2.VALUE, 120)
FROM #tmpgroupby t2
where t1.ID = t2.ID
AND t1.code = t2.CODE
FOR XML PATH (''))
, 1, 1, '')
FROM #tmpgroupby t1
GROUP BY ID,CODE
--- below also give the same result
SELECT ID, Code, STRING_AGG(VALUE,',') AS Value
FROM dbo.#tmpgroupby
GROUP BY ID, Code;
DROP TABLE #tmpgroupby
For Sql Server:
SELECT ID, CODE,
Value=STUFF((SELECT distinct ',' + Value FROM table_name t1
WHERE t.Code = t1.Code FOR XML PATH ('')), 1, 1, '')
FROM table_name AS t
GROUP BY ID, Code

SQL server code to split 2 delimited columns into rows using the elements' order

Table name: D_order
OrderID OrderName
11,12 A:B
13,14 C:D
Output required
OrderID OrderName
11 A
12 B
13 C
14 D
Recursive function might help
check this Answer https://stackoverflow.com/a/5493616/6631280
or Check this fiddle http://sqlfiddle.com/#!18/f54fd/10
;WITH tmp(OrderID, OrderName, String) AS
(
SELECT
OrderID,
OrderName,
LEFT(String, CHARINDEX(',', String + ',') - 1),
STUFF(String, 1, CHARINDEX(',', String + ','), '')
FROM Testdata
UNION all
SELECT
OrderID,
OrderName,
LEFT(String, CHARINDEX(',', String + ',') - 1),
STUFF(String, 1, CHARINDEX(',', String + ','), '')
FROM tmp
WHERE
String > ''
)
SELECT
OrderID,
OrderName,
FROM tmp
ORDER BY OrderID
If you have SQL Server 2016+, you may try an approach, based on JSON. Just transform the data into valid JSON arrays and parse these arrays with OPENJSON(). The result is a table with columns key, value and type, and the key column holds the index of the element in these arrays. With this approach you can parse more than two elements.
Table:
CREATE TABLE Data (
OrderID nvarchar(100),
OrderName nvarchar(100)
)
INSERT INTO Data
(OrderID, OrderName)
VALUES
('11,12', 'A:B'),
('13,14', 'C:D'),
('15,16,17,18', 'E:F:G:H')
Statement:
SELECT j1.[value] AS OrderId, j2.[value] AS OrderName
FROM Data d
CROSS APPLY OPENJSON(CONCAT(N'[', d.OrderId, N']')) j1
CROSS APPLY OPENJSON(CONCAT(N'["', REPLACE(d.OrderName, N':', N'","'), N'"]')) j2
WHERE j1.[key] = j2.[key]
Result:
-----------------
OrderId OrderName
-----------------
11 A
12 B
13 C
14 D
15 E
16 F
17 G
18 H
You should split the strings and make union. I used approach for spliting string described here.
The code:
SELECT substring(OrderId, 1, CHARINDEX(',',OrderId)-1) OrderId,
substring(OrderName, 1, CHARINDEX(':',OrderName)-1) OrderName
FROM YourDataTable
UNION ALL
SELECT substring(OrderId, CHARINDEX(',',OrderId)+1, LEN(OrderId)),
substring(OrderName, CHARINDEX(':',OrderName)+1, LEN(OrderName))
FROM YourDataTable
This works only for the formatting in the sample data.

Not able to separate delimited data in sqlserver [duplicate]

This question already has answers here:
T-SQL split string
(27 answers)
Closed 3 years ago.
I have column named Description, in that the rows are inserted along with a delimiter '-'.
I used the query to separate it. The query is mentioned below
select Description from Sheet1$
cross apply
SplitString('Description','-')
The columns have following data
Description
00000131-125
0000154-4625-4569-4568-45213
Try this below
DECLARE #Str AS TABLE ([Description] varchar(max) )
INSERT INTO #Str
SELECT '00000131-125' UNION ALL
SELECT '0000154-4625-4569-4568-45213'
SELECT Id,
LTRIM(RTRIM(Split.a.value('.','nvarchar(100)'))) AS [Description]
FROM
(
SELECT
ROW_NUMBER()OVER(ORDER BY (SELECT Null)) AS Id,
CAST('<S>'+(REPLACE([Description],'-','</S><S>')+'</S>') AS XML ) AS [Description]
FROM #Str
)AS A
CROSS APPLY [Description].nodes('S') AS Split(a)
Adding FOR XML PATH to the end of a query allows you to output the results of the query as XML elements, with the element name contained in the PATH argument.
Result
Id Description
---------------
1 00000131
1 125
2 0000154
2 4625
2 4569
2 4568
2 45213

Get a specific string

It's my data and every ThroughRouteSid record has the same pattern.
six number and five comma. then I just want to get three and five
number into two record to template Table and get the same Count()
value to these two record.
For example: First record in the picture.
ThroughRouteSid(3730,2428,2428,3935,3935,3938,) Count(32).
I want a result like this:
2428 32 3935 32
I get What number I want.become two record and both have same Count value into template table
you can use XML to get your result, please refer below sample code -
create table #t1( ThroughRouteSid varchar(500) , Cnt int)
insert into #t1
select '3730,2428,2428,3935,3935,3938,' , len('3730,2428,2428,3935,3935,3938,')
union all select '1111,2222,3333,4444,5555,6666,' , len('1111,2222,3333,4444,5555,6666,')
select cast( '<xml><td>' + REPLACE( SUBSTRING(ThroughRouteSid ,1 , len(ThroughRouteSid)-1),',','</td><td>') + '</td></xml>' as xml) XmlData , Cnt
into #t2 from #t1
select XmlData.value('(xml/td)[3]' ,'int' ), Cnt ,XmlData.value('(xml/td)[5]' ,'int' ), Cnt
from #t2
First create the function referring How to Split a string by delimited char in SQL Server. Then try Querying the following
select (SELECT CONVERT(varchar,splitdata) + ' '+ Convert(varchar, [Count])+' ' FROM (select splitdata, ROW_NUMBER() over (ORDER BY (SELECT 100)) row_no
from [dbo].[fnSplitString](ThroughRouteSid,',')
where splitdata != '') as temp where row_no in (2,5)
for xml path('')) as col1 from [yourtable]
If you are using SQL Server 2016 you can do something like this:
create table #temp (ThroughRouteSid varchar(1024),[Count] int)
insert into #temp values
('3730,2428,2428,3935,3935,3938,',32),
('730,428,428,335,935,938,',28)
select
spt.value,
t.[Count]
from #temp t
cross apply (
select value from STRING_SPLIT(t.ThroughRouteSid,',') where LEN(value) > 0
)spt

how to write SQL query for this result?

I have so many long database so I used seq_no in commas separate using more than one sequence store in single column but now I want all sequence in a single column so I am confused how to create this sql result for this.
For example:
TABLE STRUCTURE
SR_NO IS INT ,
SEQ_NO IS VARCHAR(MAX)
SR_NO SEQ_NO
---------------------------------
1 1839073,
2 1850097,1850098,
3 1850099,1850100,1850110
I need to get this result:
SEQ_NO
--------------
1839073
1850097
1850098
1850099
1850100
1850110
Thanks!
declare #t table(Id int,seq varchar(100))
insert into #t (Id,seq) values (1,'1839073,'),(2,'1839073,1850098,'),(3,'1850099,1850100,1850110 ')
;With Cte as (
SELECT A.Id,
Split.a.value('.', 'VARCHAR(100)') AS Seq
FROM
(
SELECT Id,
CAST ('<M>' + REPLACE(seq, ',', '</M><M>') + '</M>' AS XML) AS Data
FROM #t
) AS A CROSS APPLY Data.nodes ('/M') AS Split(a) )
Select ID,Seq from Cte Where Seq > ''
Try splitting it with XML
SELECT SR_NO, t.c.value('.', 'VARCHAR(2000)') COL1
FROM (
SELECT SR_NO, x = CAST('<t>' +
REPLACE(SEQ_NO, ',', '</t><t>') + '</t>' AS XML)
FROM
(values(1,'1839073'),(2, '1850097,1850098'),
(3, '1850099,1850100,1850110')) y(SR_NO, SEQ_NO)
) a
CROSS APPLY x.nodes('/t') t(c)
Result:
SR_NO COL1
1 1839073
2 1850097
2 1850098
3 1850099
3 1850100
3 1850110
You can replace this with your table:
(values (1,'1839073'),(2, '1850097,1850098'),
(3, '1850099,1850100,1850110')) y(SR_NO, SEQ_NO)
This should do it: (Replace YourTableName with your table name)
;WITH CTE(NEW_SEQ_NO, SEQ_NO) as (
SELECT LEFT(SEQ_NO, CHARINDEX(',',SEQ_NO + ',') -1),
STUFF(SEQ_NO, 1, CHARINDEX(',',SEQ_NO + ','), '')
FROM YourTableName
WHERE SEQ_NO <> '' AND SEQ_NO IS NOT NULL
UNION all
SELECT LEFT(SEQ_NO, CHARINDEX(',',SEQ_NO + ',') -1),
STUFF(SEQ_NO, 1, CHARINDEX(',',SEQ_NO + ','), '')
FROM CTE
WHERE SEQ_NO <> '' AND SEQ_NO IS NOT NULL
)
SELECT NEW_SEQ_NO from CTE ORDER BY NEW_SEQ_NO
You can check this topic for more information:
Turning a Comma Separated string into individual rows
I have written the following query after referring Turning a Comma Separated string into individual rows
It will work for you
create table STRUCTURE(SR_NO int, SEQ_NO varchar(max))
insert STRUCTURE select 1, '1839073,'
insert STRUCTURE select 2, '1850097,1850098,'
insert STRUCTURE select 3, '1850099,1850100,1850110'
;with tmp(SR_NO, DataItem, SEQ_NO) as (
select SR_NO, LEFT(SEQ_NO, CHARINDEX(',',SEQ_NO+',')-1),
STUFF(SEQ_NO, 1, CHARINDEX(',',SEQ_NO+','), '')
from STRUCTURE
union all
select SR_NO, LEFT(SEQ_NO, CHARINDEX(',',SEQ_NO+',')-1),
STUFF(SEQ_NO, 1, CHARINDEX(',',SEQ_NO+','), '')
from tmp
where SEQ_NO > ''
)
Select DataItem as SEQ_NO from tmp order by SEQ_NO;