How to split string in SQL Server - sql

I'm trying to split the value from the model_interested column so that from the whole data only model display
SELECT SUBSTRING(model_interested, 20, CHARINDEX('model', model_interested)) AS model_interested
FROM cust
From the image in model_interested column I wish to only display
"model":"A180"
"model":"A200 AMG FL"
I have tried splitting by number of characters but I don't think it's the right way.

You can use the following solution using SUBSTRING and CHARINDEX:
SELECT SUBSTRING(model_interested, CHARINDEX('"model":"', model_interested) + LEN('"model":"'), CHARINDEX('"', model_interested, CHARINDEX('"model":"', model_interested) + LEN('"model":"')) - (CHARINDEX('"model":"', model_interested) + LEN('"model":"')))
FROM table_name
To get the whole property (with property name and value) you can use the following solution:
SELECT SUBSTRING(model_interested, CHARINDEX('"model":"', model_interested), CHARINDEX('"', model_interested, CHARINDEX('"model":"', model_interested) + LEN('"model":"')) - CHARINDEX('"model":"', model_interested) + 1)
FROM table_name
You can also use JSON_VALUE to get the expected value, but you have to change the data to a valid JSON value:
SELECT JSON_VALUE(REPLACE(REPLACE(model_interested, '{[', '[{'), ']}', '}]'), '$[0].model')
FROM table_name
demo on dbfiddle.uk

If using earlier version of SQL server than 2016, then you can write a query as:
;with cte as
(
SELECT
Split.a.value('.', 'VARCHAR(100)') AS model_interested
FROM (
SELECT CAST ('<M>' + REPLACE([model_interested], '.', '</M><M>') + '</M>' AS XML)
as model_interested_xml
FROM #cust
) AS A CROSS APPLY model_interested_xml.nodes ('/M') AS Split(a)
)
select model_interested
from cte
where CHARINDEX('model',model_interested) > 0
demo here: https://rextester.com/CCW41495

Related

Select text from between two characters in string

I have data in database an example of data below
folder/subfolder/file/doc
folder/subfolder/doc
how do I get the 1st instance of characters from between the '/'
I want to extract 'folder/subfolder'
I have tried the following but not what I need. this gets 'folder/'
LEFT([Cat], CHARINDEX('/', [Cat]) ) as 'doc_cat',
and the below gets the last part
RIGHT([Cat], CHARINDEX('/', [Cat]) ) as 'doc_cat2',
I want to get the 1st part of and second part of string
Here is one method:
select left(doc_cat_1, charindex('/', doc_cat_1) - 1)
from t cross apply
(select stuff(cat, 1, charindex('/', cat), '') as doc_cat_1
) v1;
The string handling capabilities of SQL Server are pretty lousy. Apply at least makes it easier to handle intermediate results.
You can use LEFT and CHARINDEX
LEFT([Cat],charindex('/',[Cat],charindex('/',[Cat])+1)-1) AS 'doc_cat'
One more way to accomplish using XML -
declare #s table(patterns nvarchar(100))
insert into #s
values ('folder/subfolder/file/doc'), ('folder/subfolder/doc'),('folder/subfolder')
select cast(concat('<x>', REPLACE(patterns, '/', '</x><x>'), '</x>') as xml).value('/x[1]','varchar(100)') + '/'
+ cast(concat('<x>', REPLACE(patterns, '/', '</x><x>'), '</x>') as xml).value('/x[2]','varchar(100)')
from #s
If you're on SQL 2016 or newer, you could use STRING_SPLIT()
WITH cte AS (
SELECT cat, value, ROW_NUMBER() OVER (PARTITION BY cat ORDER BY cat) rn
FROM someTable CROSS APPLY
STRING_SPLIT(cat,'/')
)
SELECT cat, value FROM cte WHERE rn = 2;
The advantage here is that rn could be any number you need.
Fiddle here.

Split values into separate rows

WITH Numbers AS (SELECT Table.ProductNumber FROM Table WITH (NOLOCK))
returns ProductNumber like 1, 2, 3,4,5 - some are comma separated, so I want to split and than do proper SELECT on them with WHERE
What I got so far is:
SELECT #XML = CONVERT(xml,'<root><s>' + REPLACE(Numbers , ',' ,'</s><s>') + '</s></root>')
SELECT [ProductNumber ] = T.c.value('.','varchar(60)') FROM #XML.nodes('/root/s') T(c)
But I dont know how to convert selected SQL resource Numbers into string for XML conversion and not loose track of which ProductNumber were in which row
The problem in your query is you are assigning the converted xml to a variable, but here only the last row will be stored in that variable.
Try something like this.
SELECT Split.a.value('.', 'VARCHAR(100)') splt_num
FROM (SELECT Cast ('<M>'
+ Replace(ProductNumber, ',', '</M><M>')
+ '</M>' AS XML) AS Data
FROM yourtable) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)

Check the column contains string or not in sql

I have comma-separated string like 675,899,343,294,988.
My table has values like,
ID Values
1 56,78,485
2 90,343,398
3 756,46774,45,4
4 536,394,988
Here i want result like : ID 2,values 343 and ID 4,values 988
Here you can split values to each row for each Id.
;WITH CTE AS
(
-- Convert CSV to rows
SELECT ID,LTRIM(RTRIM(Split.a.value('.', 'VARCHAR(100)'))) 'VALUES'
FROM
(
-- To change ',' to any other delimeter, just change ',' before '</M><M>' to your desired one
SELECT ID,CAST ('<M>' + REPLACE([Values], ',', '</M><M>') + '</M>' AS XML) AS Data
FROM YourTable
) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)
)
SELECT *
FROM CTE
WHERE (ID=2 AND [VALUES]='343') OR (ID=4 AND [VALUES]='988')
EDIT :
If you want to get matching Id, you can do the below
SAMPLE TABLE
SELECT * INTO #TEMP
FROM
(
SELECT 1 ID, '56,78,485' [Values]
UNION ALL
SELECT 2, '90,343,398'
UNION ALL
SELECT 3, '756,46774,45,4'
UNION ALL
SELECT 4, '536,394,988'
)TAB
QUERY
DECLARE #STR VARCHAR(100)='675,899,343,294,988'
;WITH CTE1 AS
(
SELECT LTRIM(RTRIM(Split.a.value('.', 'VARCHAR(100)'))) 'String'
FROM
(
-- To change ',' to any other delimeter, just change ',' before '</M><M>' to your desired one
SELECT CAST ('<M>' + REPLACE(#STR, ',', '</M><M>') + '</M>' AS XML) AS Data
) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)
)
,CTE2 AS
(
-- Convert CSV to rows
SELECT ID,LTRIM(RTRIM(Split.a.value('.', 'VARCHAR(100)'))) 'Values'
FROM
(
-- To change ',' to any other delimeter, just change ',' before '</M><M>' to your desired one
SELECT ID,CAST ('<M>' + REPLACE([Values], ',', '</M><M>') + '</M>' AS XML) AS Data
FROM #TEMP
) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)
)
SELECT C2.*
FROM CTE1 c1
JOIN CTE2 C2 ON C1.String=C2.[VALUES]
You can use
SELECT `id` FROM `table` WHERE `Values` IN(string)

Group by Clause on a query SQL

I have managed to separate semi colon separated value to multiple rows in sql 2008 what i need now i to have Count(*) statement on it
ID Answers
1 Agent;Department Store
2 Distributor;Wholesaler
using
SELECT ID,
Split.a.value('.', 'VARCHAR(100)') AS String
FROM (SELECT ID,
CAST ('<M>' + REPLACE(Question1, '; ', '</M><M>') + '</M>' AS XML) AS String
FROM Registrations) AS A CROSS APPLY String.nodes ('/M') AS Split(a)
I can get
ID String
1 Agent
1 Department Store
2 Distributor
2 Wholesaler
i just need to get the count(*) of Agent,Department store ..
can i do something like
Select Count(*),String from ( ..above query.. ) group by string ?!
Your attempted query is correct it does work
Do this
select count(*) as Count1,String from
(
SELECT ID,
Split.a.value('.', 'VARCHAR(100)') AS String
FROM (SELECT ID,
CAST ('<M>' + REPLACE(Answers, ';', '</M><M>') + '</M>' AS XML) AS String
FROM #t) AS A CROSS APPLY String.nodes ('/M') AS Split(a)
)x
group by x.String
OR like this?
select count(*) as Count1 from
(
SELECT ID,
Split.a.value('.', 'VARCHAR(100)') AS String
FROM (SELECT ID,
CAST ('<M>' + REPLACE(Answers, ';', '</M><M>') + '</M>' AS XML) AS String
FROM #t) AS A CROSS APPLY String.nodes ('/M') AS Split(a)
)x
SEE DEMO

How to convert string of numbers ( '14, 72' ) to numbers in sql query

declare #lkaklf as varchar(Max)
Select ss.Data from SplitString('14,72', ',') as ss
Select #lkaklf = CONVERT(varchar, COALESCE( + #lkaklf + ',', '') + '''' + Data + '''') From
(
Select Data from SplitString('14,72', ',')
)de
select #lkaklf
print #lkaklf
Select * from LPO Where CONVERT(varchar, LPO.LocalPurchaseOrderId) in (#lkaklf)
#lkalf value is Printing in message but not coming into select query... Why ?
You cannot do what you want. I would recommend that you skip over the splitting part of the query and just do:
where ','+#lkaklf+',' like ','+cast(LPO.LocalPurchaseOrderId as varchar(255))+',%'
That is, just use string comparisons.
If you really want to use SplitString(), then put the results in a temporary table:
insert into #t
select data from splitstring('14,72', ',')
And then use a subquery:
where cast(#lkalklf as varchar(255)) in (select data from #t)