Check the column contains string or not in sql - 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)

Related

Inserting 2 delimited strings into SQL Server

I have a simple select statement that can take a string of prodcodes from a table called WCvsNIRTemps and show them in individual rows.
SELECT
Split.a.value('.', 'VARCHAR(100)') AS ProdCodes
FROM (SELECT
CAST ('<M>' + REPLACE([ProdCodes], ',', '</M><M>') + '</M>' AS XML) AS String
FROM WCvsNIRTemps where TemplateName = 'TempName') AS A CROSS APPLY String.nodes ('/M') AS Split(a)
How can I go about showing two columns of data? The delimited string contains the correct order for both of them. So the first listed prodcode ties to the first item listed in the new column prodnam which I'd like to show. Perhaps a pivot table would be a smart idea. Here is my attempt.
SELECT
Split.a.value('.', 'VARCHAR(100)') AS ProdCodes, Split2.b.value('.', 'VARCHAR(100)') AS ProdNams
FROM (SELECT
CAST ('<M>' + REPLACE([ProdCodes], ',', '</M><M>') + '</M>' AS XML) AS String
FROM WCvsNIRTemps where TemplateName = 'TempName') AS A
CROSS APPLY String.nodes ('/M') AS Split(a),
(SELECT
CAST ('<M>' + REPLACE([ProdNams], ',', '</M><M>') + '</M>' AS XML) AS String
FROM WCvsNIRTemps where TemplateName = 'TempName') AS B
CROSS APPLY String.nodes ('/M') AS Split2(b)
WCvsNIRtemps Table:
**TemplateName | ProdCodes | Prodnams**
TempName prodc1,prodc2,prodc3 prodn1,prodn2,prodn3
Desired Query Output:
**Prodcode | Prodnam**
prodc1 prodn1
prodc2 prodn2
prodc3 prodn3
Try below, it will help you :
;WITH CTE AS(
SELECT M.N.value('.[1]','VARCHAR(8000)') AS PRODUCT_CODES, ROW_NUMBER() over(order by M.N.value('.[1]','VARCHAR(8000)') ASC) as Prod_ID,
P.Q.value('.[1]','VARCHAR(8000)') AS PRODUCT_NAMES, ROW_NUMBER() over(order by P.Q.value('.[1]','VARCHAR(8000)') ASC) as ProdName_ID
FROM
(
SELECT CAST('<XMLROOT><ROWDATA>' + REPLACE(PRODCODES,',','</ROWDATA><ROWDATA>') + '</ROWDATA></XMLROOT>' AS XML) AS X,
CAST('<XMLROOT><ROWDATA>' + REPLACE(PRODNAMS,',','</ROWDATA><ROWDATA>') + '</ROWDATA></XMLROOT>' AS XML) AS Y
FROM TEMPTABLE
)T
CROSS APPLY X.nodes('/XMLROOT/ROWDATA')M(N)
CROSS APPLY Y.nodes('/XMLROOT/ROWDATA')P(Q))
SELECT DISTINCT A.PRODUCT_CODES,B.PRODUCT_NAMES FROM CTE A INNER JOIN CTE B
ON A.PROD_ID=B.PRODNAME_ID ORDER BY A.PRODUCT_CODES
It will give below output :
I hope this help. I would like to thanks my friend Bhushan for helping me in this.

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;

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)

Costful XML sql operation

This query works, but it's cost is very big, how to get same result but with less cost?
SELECT ProductID, Split.a.value('.', 'NVARCHAR(60)') ProductNumber FROM (
SELECT ProductID, Cast ('<M>' + Replace(ProductNumber, ',', '</M><M>') + '</M>' AS XML) AS Data FROM Table
) AS A CROSS APPLY Data.nodes ('/M') AS Split(a)

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