Convert Column Values into comma separated str - sql

I have a table #f with the following data
ID
Number
V2
28
V2
29
V2
30
I would like my desired output to have
ID
Number
V2
28,29,30
How could I achieve this?
I've tried using the STUFF function but I get an error
Error converting data type varchar to numeric.
This is the code I have:
SELECT
#f.id,
number = STUFF((SELECT DISTINCT ',' + f.id
FROM #f f
WHERE f.number = number
FOR XML PATH('')), 1, 1, '')
FROM
#f
GROUP BY
#f.id

Here's a simple solution utilizing string_agg.
select ID
,string_agg(Number, ',') as Number
from t
group by ID
ID
Number
V2
28,29,30
Fiddle

Related

Error converting data type varchar to bigint when trying to concatenate column row values

I have the following query that I am using to concatenate the row values of a column into a single value.
SELECT
SUBSTRING(
(
SELECT
',' + id_number AS 'data()'
FROM
users FOR XML PATH('')
),
2,
9999
) AS id_numbers
The id_number column is of type varchar. I have tried to convert to text but still getting errors.
id_number is a bigint, you'll need to CONVERT or CAST it to a text type:
SELECT
SUBSTRING(
(
SELECT
',' + CONVERT( varchar(20), id_number ) AS 'data()'
FROM
users FOR XML PATH('')
),
2,
9999
) AS id_numbers
If you're using SQL Server 2017 or later you can use STRING_AGG (MS SQL Server's equivalent to MySQL's GROUP_CONCAT):
SELECT
STRING_AGG( id_number, ', ' )
(SQL Server will handle the implicit bigint-to-varchar conversion for you as there's no ambiguousness introduced by the use of binary operators).

SQL Server 2016 data type conversion error

I have the below query. I am using multiple SELECT statements as the tool I am working with requires the FROM clause in the first line with a single SELECT value, for some reason.
DOCUMENT_ID is an integer type column. I need the DOCUMENT_IDs as a comma separated values, as the output from this query. (Ex. 1234,7786, 6478, 5835)
The problem is that I am running into the below error. Can someone please help.
Conversion failed when converting the varchar value ',' to data type int.
I read some post regarding using converting to NVARCHAR using CAST, however I am running into syntax errors doing the same. Where exactly could it be applied?
SELECT DOCUMENT_ID FROM (
SELECT STUFF
(
(
SELECT ',' + em.DOCUMENT_ID
FROM(
SELECT distinct a.DOCUMENT_ID AS DOCUMENT_ID FROM A_DOCUMENT a
inner join PRICE_RECORD wk ON a.DOCUMENT_ID = wk.DOCUMENT_ID
WHERE a.APPROVAL_STATUS = 'Submitted'
) em
ORDER BY em.DOCUMENT_ID FOR XML PATH('')
),
1, 1, '') AS DOCUMENT_ID
) AS Output
Thanks.
If DOCUMENT_ID is an int then replace ',' + em.DOCUMENT_ID with one of the following:
CONCAT(',', em.DOCUMENT_ID) --SQL Server 2012+
',' + CONVERT(varchar(10),em.DOCUMENT_ID)
--Or, if you prefer CAST
',' + CAST(em.DOCUMENT_ID AS varchar(10))
int has a higher datatype precedence than a varchar, therefore your comma (',') was being implicity converted to an int, which was causing a conversion error.

Replace all numbers with three digits or more

I have a field say "keywords" which contains random strings of numbers and I'd like to clean the field from any string of numbers which has more than 3 digits.
I have searched and know wildcards are not possible in replace. Any idea how I can go about that?
Here's a good place to start
Say you have a table called "test_test":
create table dbo.test_test (thisStuff varchar(100));
With a value like this in it:
insert into test_test values ('Hello123 this is 12 a test 22983o398r57298298347238');
You can do some limited pattern matching with patindex():
select substring(thisStuff,
1,
patindex('%[0-9][0-9][0-9]%',thisStuff)-1) +
substring(thisStuff,
patindex('%[0-9][0-9][0-9]%',thisStuff)+3,
len(thisStuff))
from test_test
Which converts this value:
Hello123 this is 12 a test 22983o398r57298298347238
Into this value:
Hello this is 12 a test 22983o398r57298298347238
In update form it would look like this:
update test_test set thisStuff =
substring(thisStuff,
1,
patindex('%[0-9][0-9][0-9]%',thisStuff)-1) +
substring(thisStuff,
patindex('%[0-9][0-9][0-9]%',thisStuff)+3,
len(thisStuff));
Which, when run over and over, gives you the progressive values:
Hello this is 12 a test 83o398r57298298347238
Hello this is 12 a test 83or57298298347238
Hello this is 12 a test 83or98298347238
Hello this is 12 a test 83or98347238
Hello this is 12 a test 83or47238
Hello this is 12 a test 83or38
Before erroring out
Msg 3621, Level 0, State 0.
The statement has been terminated.
Msg 537, Level 16, State 2.
Invalid length parameter passed to the LEFT or SUBSTRING function. (Line 35)
Since you are on 2016, you can use String_Split() in concert with Try_Convert()
Example
Declare #YourTable table (idproduct int,searchkeywords varchar(500))
Insert Into #YourTable values
(109070,'stands & cabinets kantec ams300 1010055 43212002 03906786808 7503 ktkams ltk ams 300')
Select A.idproduct
,NewString = B.S
From #YourTable A
Cross Apply (
Select S = Stuff((Select ' ' +Value
From (Select Value,Seq=Row_Number() over (Order by (select null))
From String_Split(A.searchkeywords,' ')
) B1
Where (try_convert(float,Value) is null)
or (try_convert(float,Value) is not null and len(Value)<=3)
Order by Seq
For XML Path ('')),1,1,'')
) B
Returns
idproduct NewString
109070 stands & cabinets kantec ams300 ktkams ltk ams 300
If you are satisfied with the results, you can apply an update like so:
Update A Set searchkeywords = B.S
From #YourTable A
Cross Apply (
Select S = Stuff((Select ' ' +Value
From (Select Value,Seq=Row_Number() over (Order by (select null))
From String_Split(A.searchkeywords,' ')
) B1
Where (try_convert(float,Value) is null)
or (try_convert(float,Value) is not null and len(Value)<=3)
Order by Seq
For XML Path ('')),1,1,'')
) B

SQL Server: Convert comma separated values in a string into buckets based on the values

Have a string "A,B,H1,J,P1,H3,L2" in a column. Need to segregate this into rows based on the number appended/not appended with each. So for the above example I should have 4 rows as output:
ABJ (no numbers associated with it)
HP (1 appended to it)
L (2 appended to it)
H (3 appended to it)
With the help of xml nodes:
DECLARE #string nvarchar(max) = 'A,B,H1,J,P1,H3,L2',
#xml xml
SELECT #xml = CAST('<a>' + REPLACE(#string,',','</a><a>') +'</a>' as xml)
;WITH cte AS (
SELECT t.v.value('.','nvarchar(10)') as v,
CASE WHEN TRY_CAST(RIGHT(t.v.value('.','nvarchar(10)'),1) as int) IS NULL THEN 0
ELSE CAST(RIGHT(t.v.value('.','nvarchar(10)'),1) as int) END as g
FROM #xml.nodes('/a') as t(v)
)
SELECT REPLACE((
SELECT v +''
FROM cte c1
WHERE c1.g= c.g
FOR XML PATH ('')
),g,'') as [values]
FROM cte c
GROUP BY g
ORDER BY g
Output:
values
------
ABJ
HP
L
H

How to Add all values given in comma separated in sql

How to get the SUM of values of one column in table. Now I want get the SUM of 8 and 0 if I use query write below.
SELECT SUM(Items) FROM dbo.CustomSplit(#AssigneeProgress,',')
this gives an error
Operand data type varchar is invalid for sum operator.
My code is:
DECLARE #AssigneeProgress AS VARCHAR(100)
SELECT
#AssigneeProgress = STUFF((SELECT ',' + CAST(ISNULL((((TblAssignments.PlannedDuration * 100) / 300) * TblAssignments.Progress) / 100,0) AS VARCHAR(100))
FROM TblTasks,TblAssignments
WHERE TblTasks.TaskId = TblAssignments.AssignmentEntityId
AND TblAssignments.AssignmentEntity = 'Task'
AND AssignmentStatus NOT IN ('Deleted','Cancelled')
AND TblTasks.TaskId = 63 FOR XML PATH('')), 1, 1,'')
SELECT * FROM dbo.CustomSplit(#AssigneeProgress,',')
This query gives me the result in table like
Items
8
0
Does your method CustomSplit return a table having the column Items of type varchar?
If yes, you can convert the column:
SELECT SUM(cast(Items as int)) FROM dbo.CustomSplit(#AssigneeProgress,',')
Try to cast the Items that you get back from your split function to an INT type before summing:
SELECT
SUM(CAST(Items AS INT))
FROM
dbo.CustomSplit(#AssigneeProgress,',')
The CustomSplit function most likely returns varchar(x) items....