SQL 2016 has a new feature which converts data on SQL server to JSON. I am having difficulty in combining array of objects into array of values i.e.,
EXAMPLE -
CREATE TABLE #temp (item_id VARCHAR(256))
INSERT INTO #temp VALUES ('1234'),('5678'),('7890')
SELECT * FROM #temp
--convert to JSON
SELECT (SELECT item_id
FROM #temp
FOR JSON PATH,root('ids'))
RESULT -
{
"ids": [{
"item_id": "1234"
},
{
"item_id": "5678"
},
{
"item_id": "7890"
}]
}
But I want the result as -
"ids": [
"1234",
"5678",
"7890"
]
Can somebody please help me out?
Thanks! The soultion we found is converting into XML first -
SELECT
JSON_QUERY('[' + STUFF(( SELECT ',' + '"' + item_id + '"'
FROM #temp FOR XML PATH('')),1,1,'') + ']' ) ids
FOR JSON PATH , WITHOUT_ARRAY_WRAPPER
Martin!
I believe this is an even simpler way of doing it:
SELECT '"ids": ' +
REPLACE(
REPLACE( (SELECT item_id FROM #temp FOR JSON AUTO),'{"item_id":','' ),
'"}','"' )
declare #temp table (item_id VARCHAR(256))
INSERT INTO #temp VALUES ('1234'),('5678'),('7890')
SELECT * FROM #temp
--convert to JSON
select
json_query(QUOTENAME(STRING_AGG('"' + STRING_ESCAPE(item_id, 'json') + '"', char(44)))) as [json]
from #temp
for json path
When we want to concatenate strings as json array then:
escape string - STRING_ESCAPE
concatenate string with comma separator - STRING_AGG, comma ascii code is 44
add quotation it in brackets - QUOTENAME (without param)
return string (with array of elements) as json - JSON_QUERY
Since arrays of primitive values are valid JSON, it seems strange that a facility for selecting arrays of primitive values isn't built into SQL Server's JSON functionality. (If on the contrary such functionality exists, I at least haven't been able to discover it after quite a bit of searching).
The approach outlined above works as described. But when applied for a field in a larger query, the array of primitives is surrounded with quotes.
E.g., this
DECLARE #BomTable TABLE (ChildNumber dbo.udt_ConMetPartNumber);
INSERT INTO #BomTable (ChildNumber) VALUES (N'101026'), (N'101027');
SELECT N'"Children": ' + REPLACE(REPLACE((SELECT ChildNumber FROM #BomTable FOR JSON PATH), N'{"ChildNumber":', N''), '"}','');
works by producing:
"Children": ["101026,"101027]
But, following the approach above, this:
SELECT
p.PartNumber,
p.Description,
REPLACE(REPLACE((SELECT
ChildNumber
FROM
Part.BillOfMaterials
WHERE
ParentNumber = p.PartNumber
ORDER BY
ChildNumber
FOR
JSON AUTO
), N'{"ChildNumber":', N''), '"}', '"') AS [Children]
FROM
Part.Parts AS p
WHERE
p.PartNumber = N'104444'
FOR
JSON PATH
Produces:
[
{
"PartNumber": "104444",
"Description": "ASSY HUB R-SER DRIV HP10 ABS",
"Children": "[\"101026\",\"101027\",\"102291\",\"103430\",\"103705\",\"104103\"]"
}
]
Where the Children array is wrapped as a string.
This version (building on the others):
correctly escapes an special JSON characters (e.g. quotes)
returns an empty array [] for no data
Requires SQL 2017 or later (due to STRING_AGG):
SELECT
CONCAT('[',
(SELECT STRING_AGG('"' + STRING_ESCAPE(item_id, 'json') + '"', ',')
FROM #temp)
, ']')
Here's a wild idea that may or may not be practical. Recurse over your data set and append things to your JSON arrays using JSON_MODIFY:
with
d (d) as (select * from (values (1),(2),(3),(4)) t (d)),
j (d, j) as (
-- Adapt the recursion to make it dynamic
select 1, json_modify('[]', 'append $', d)
from d
where d = 1
union all
select d.d, json_modify(j, 'append $', d.d)
from d join j on d.d = j.d + 1
)
select *
from j;
I kept it simple for illustration purposes. You'll adapt it to make it dynamic, of course. This produces:
|d |j |
|---|---------|
|1 |[1] |
|2 |[1,2] |
|3 |[1,2,3] |
|4 |[1,2,3,4]|
Could even be used to emulate standard SQL JSON_ARRAYAGG
Most of these solutions are essentially creating a CSV that represents the array contents, and then putting that CSV into the final JSON format. Here's what I use, to avoid XML:
DECLARE #tmp NVARCHAR(MAX) = ''
SELECT #tmp = #tmp + '"' + [item_id] + '",'
FROM #temp -- Defined and populated in the original question
SELECT [ids] = JSON_QUERY((
SELECT CASE
WHEN #tmp IS NULL THEN '[]'
ELSE '[' + SUBSTRING(#tmp, 0, LEN(#tmp)) + ']'
END
))
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
Related
Say I have a JSON data stored in a varchar(max) column in a database. Is it possible to use SQL to get all the JSON paths present in that data. For example for the following JSON:
{
"dog":
{
"name":"Rover",
"age": 6,
"likes:["catch", "eating"]
}
}
I would get the output of:
$.
$.dog
$.dog.name
$.dog.age
$.dog.likes[0]
$.dog.likes[1]
I have looked at functions including json_query and json_value but they seem to be more about getting data from the JSON rather than the metadata I require.
I am using SQL Server 2018.
Try a recursive CTE
DECLARE #s varchar(max) = '{
"dog":
{
"name":"Rover",
"age": 6,
"likes":["catch", "eating"]
}
}';
with cte as (
select [type], '$' + case when roottype = 4 then '['+[key]+']' else '.'+[key] end as path
from (
select r.[type] , dummy.[type] roottype, r.[key]
from OPENJSON('{"dummy":' + #s +'}', '$') dummy
cross apply OPENJSON(#s, '$') r
) t
union all
select j.[type], path + case when cte.[type] = 4 then '['+j.[key]+']' else '.'+j.[key] end
from cte
cross apply OPENJSON(#s, path) j
where cte.[type] >= 4
)
select *
from cte;
Returns
type path
5 $.dog
1 $.dog.name
2 $.dog.age
4 $.dog.likes
1 $.dog.likes[0]
1 $.dog.likes[1]
SQL 2016 has a new feature which converts data on SQL server to JSON. I am having difficulty in combining array of objects into array of values i.e.,
EXAMPLE -
CREATE TABLE #temp (item_id VARCHAR(256))
INSERT INTO #temp VALUES ('1234'),('5678'),('7890')
SELECT * FROM #temp
--convert to JSON
SELECT (SELECT item_id
FROM #temp
FOR JSON PATH,root('ids'))
RESULT -
{
"ids": [{
"item_id": "1234"
},
{
"item_id": "5678"
},
{
"item_id": "7890"
}]
}
But I want the result as -
"ids": [
"1234",
"5678",
"7890"
]
Can somebody please help me out?
Thanks! The soultion we found is converting into XML first -
SELECT
JSON_QUERY('[' + STUFF(( SELECT ',' + '"' + item_id + '"'
FROM #temp FOR XML PATH('')),1,1,'') + ']' ) ids
FOR JSON PATH , WITHOUT_ARRAY_WRAPPER
Martin!
I believe this is an even simpler way of doing it:
SELECT '"ids": ' +
REPLACE(
REPLACE( (SELECT item_id FROM #temp FOR JSON AUTO),'{"item_id":','' ),
'"}','"' )
declare #temp table (item_id VARCHAR(256))
INSERT INTO #temp VALUES ('1234'),('5678'),('7890')
SELECT * FROM #temp
--convert to JSON
select
json_query(QUOTENAME(STRING_AGG('"' + STRING_ESCAPE(item_id, 'json') + '"', char(44)))) as [json]
from #temp
for json path
When we want to concatenate strings as json array then:
escape string - STRING_ESCAPE
concatenate string with comma separator - STRING_AGG, comma ascii code is 44
add quotation it in brackets - QUOTENAME (without param)
return string (with array of elements) as json - JSON_QUERY
Since arrays of primitive values are valid JSON, it seems strange that a facility for selecting arrays of primitive values isn't built into SQL Server's JSON functionality. (If on the contrary such functionality exists, I at least haven't been able to discover it after quite a bit of searching).
The approach outlined above works as described. But when applied for a field in a larger query, the array of primitives is surrounded with quotes.
E.g., this
DECLARE #BomTable TABLE (ChildNumber dbo.udt_ConMetPartNumber);
INSERT INTO #BomTable (ChildNumber) VALUES (N'101026'), (N'101027');
SELECT N'"Children": ' + REPLACE(REPLACE((SELECT ChildNumber FROM #BomTable FOR JSON PATH), N'{"ChildNumber":', N''), '"}','');
works by producing:
"Children": ["101026,"101027]
But, following the approach above, this:
SELECT
p.PartNumber,
p.Description,
REPLACE(REPLACE((SELECT
ChildNumber
FROM
Part.BillOfMaterials
WHERE
ParentNumber = p.PartNumber
ORDER BY
ChildNumber
FOR
JSON AUTO
), N'{"ChildNumber":', N''), '"}', '"') AS [Children]
FROM
Part.Parts AS p
WHERE
p.PartNumber = N'104444'
FOR
JSON PATH
Produces:
[
{
"PartNumber": "104444",
"Description": "ASSY HUB R-SER DRIV HP10 ABS",
"Children": "[\"101026\",\"101027\",\"102291\",\"103430\",\"103705\",\"104103\"]"
}
]
Where the Children array is wrapped as a string.
This version (building on the others):
correctly escapes an special JSON characters (e.g. quotes)
returns an empty array [] for no data
Requires SQL 2017 or later (due to STRING_AGG):
SELECT
CONCAT('[',
(SELECT STRING_AGG('"' + STRING_ESCAPE(item_id, 'json') + '"', ',')
FROM #temp)
, ']')
Here's a wild idea that may or may not be practical. Recurse over your data set and append things to your JSON arrays using JSON_MODIFY:
with
d (d) as (select * from (values (1),(2),(3),(4)) t (d)),
j (d, j) as (
-- Adapt the recursion to make it dynamic
select 1, json_modify('[]', 'append $', d)
from d
where d = 1
union all
select d.d, json_modify(j, 'append $', d.d)
from d join j on d.d = j.d + 1
)
select *
from j;
I kept it simple for illustration purposes. You'll adapt it to make it dynamic, of course. This produces:
|d |j |
|---|---------|
|1 |[1] |
|2 |[1,2] |
|3 |[1,2,3] |
|4 |[1,2,3,4]|
Could even be used to emulate standard SQL JSON_ARRAYAGG
Most of these solutions are essentially creating a CSV that represents the array contents, and then putting that CSV into the final JSON format. Here's what I use, to avoid XML:
DECLARE #tmp NVARCHAR(MAX) = ''
SELECT #tmp = #tmp + '"' + [item_id] + '",'
FROM #temp -- Defined and populated in the original question
SELECT [ids] = JSON_QUERY((
SELECT CASE
WHEN #tmp IS NULL THEN '[]'
ELSE '[' + SUBSTRING(#tmp, 0, LEN(#tmp)) + ']'
END
))
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
I think the following would be easier in SQL server 2017
select
JSON_QUERY
(
'["' + STRING_AGG(t.item_id,'","') + '"]'
) as ids
from #temp t
for json auto, without_array_wrapper
I want to execute a select query on a table and I need this result in a JSON format or in an excel sheet. I want to do this using query only and I'm using SQL Server 2014.
Here is the table schema
CREATE TABLE TestTable
(
Id int primary key identity(1,1),
Name nvarchar(200),
About nvarchar(2000),
Age int,
AddressId int
)
I need to get values from Id, Name, About and Age into a JSON List
JSON AUTO would make quick work of this in but JSON support is available only in SQL Server 2016 and later, including Azure SQL Database. For a T-SQL solution in SQL 2014 and earlier, you'll need to build the JSON string yourself.
Below is an example that uses a FOR XML subquery to concatenate the result into JSON format and adds the outermost [ and ] for the array. Note that this does not handle characters that must be escaped in JSON (\ and ") so you'll need to use REPLACE to escape those if contained in your data.
SELECT '[' + STUFF((
SELECT
',{'
+ '"Id":'+CAST(Id AS varchar(10)) + ','
+ COALESCE('"Name":"' + Name + '",','')
+ COALESCE('"About":"' + About + '",','')
+ COALESCE('"Age":'+CAST(Age AS varchar(10)) + ',','')
+ COALESCE('"AddressId":'+CAST(AddressId AS varchar(10)), '')
+ '}'
FROM TestTable
FOR XML PATH(''), TYPE).value('.', 'varchar(MAX)'),1,1,'')
+ ']';
For SQL server 2017
CREATE TABLE mytable(
ID int PRIMARY KEY,
Name varchar(50),
teamName varchar(255),
Create_Date DATETIME
);
INSERT INTO mytable VALUES (1,NULL,'TEST1','2017-01-02');
INSERT INTO mytable VALUES (2,NULL,'TEST2',NULL);
INSERT INTO mytable VALUES (3,'KK','TEST3','2017-01-02');
INSERT INTO mytable VALUES (4,NULL,NULL,NULL);
Try below way here i provide an example
SELECT
ID,
Name,
teamName,
Create_Date
FROM mytable
FOR JSON AUTO
http://www.sqlfiddle.com/#!18/81350/1
JSON_F52E2B61-18A1-11d1-B105-00805F49916B
[{"ID":1,"teamName":"TEST1","Create_Date":"2017-01-02T00:00:00"},{"ID":2,"teamName":"TEST2"},{"ID":3,"Name":"KK","teamName":"TEST3","Create_Date":"2017-01-02T00:00:00"},{"ID":4}]
For below vesion of sql 2017 server:
1st create a scaler function
create FUNCTION [dbo].[udf-Str-JSON] (#IncludeHead int,#ToLowerCase int,#XML xml)
Returns varchar(max)
AS
Begin
Declare #Head varchar(max) = '',#JSON varchar(max) = ''
; with cteEAV as (Select RowNr=Row_Number() over (Order By (Select NULL))
,Entity = xRow.value('#*[1]','varchar(100)')
,Attribute = xAtt.value('local-name(.)','varchar(100)')
,Value = xAtt.value('.','varchar(max)')
From #XML.nodes('/row') As R(xRow)
Cross Apply R.xRow.nodes('./#*') As A(xAtt) )
,cteSum as (Select Records=count(Distinct Entity)
,Head = IIF(#IncludeHead=0,IIF(count(Distinct Entity)<=1,'[getResults]','[[getResults]]'),Concat('{"status":{"successful":"true","timestamp":"',Format(GetUTCDate(),'yyyy-MM-dd hh:mm:ss '),'GMT','","rows":"',count(Distinct Entity),'"},"results":[[getResults]]}') )
From cteEAV)
,cteBld as (Select *
,NewRow=IIF(Lag(Entity,1) over (Partition By Entity Order By (Select NULL))=Entity,'',',{')
,EndRow=IIF(Lead(Entity,1) over (Partition By Entity Order By (Select NULL))=Entity,',','}')
,JSON=Concat('"',IIF(#ToLowerCase=1,Lower(Attribute),Attribute),'":','"',Value,'"')
From cteEAV )
Select #JSON = #JSON+NewRow+JSON+EndRow,#Head = Head From cteBld, cteSum
Return Replace(#Head,'[getResults]',Stuff(#JSON,1,1,''))
End
-- Parameter 1: #IncludeHead 1/0
-- Parameter 2: #ToLowerCase 1/0 (converts field name to lowercase
-- Parameter 3: (Select * From ... for XML RAW)
Then use this function json conversion below query is an example
Declare #Table table (ID int,Active bit,First_Name varchar(50),Last_Name varchar(50),EMail varchar(50))
Insert into #Table values
(1,1,'John','Smith','john.smith#email.com'),
(2,0,'Jane','Doe' ,'jane.doe#email.com')
Select A.ID
,A.Last_Name
,A.First_Name
,B.JSON
From #Table A
Cross Apply (Select JSON=[dbo].[udf-Str-JSON](0,1,(Select A.* For XML Raw)) ) B
From SQL-Server 2016+, you can use JSON AUTO to return Json:
Select *
From Customers
FOR JSON AUTO;
If you expect to return just a single row, then you can add Without_Array_Wrapper after FOR JSON AUTO with a comma after the AUTO keyword, and you will get an object instead of an array:
Select *
From Customers
FOR JSON AUTO, Without_Array_Wrapper;
Note: If you add the Without_Array_Wrapper and return multiple rows, you will get a newly populated object type but won't get any error - which requires carefulness as you won't know if anything is wrong and might hit you later when exercising the data.
From SQL-Server 2016+, you can use JSON AUTO to return Json:
I know two way to return query in JSON format.
If your query is from one table or only return a single table (as usual) you can use JSON PATH or JSON AUTO
CREATE TABLE TestTable
(
Id int primary key identity(1,1),
Name nvarchar(200),
About nvarchar(2000),
Age int,
AddressId int
)
INSERT INTO dbo.TestTable(Name,About,Age,AddressId)
VALUES (N'John' , NULL ,21, 16),(N'Mehdi' , 'Developer' ,32, 15)
query is
select * from [TestTable] for JSON PATH
output :
[{
"Id": 1,
"Name": "Mehdi",
"About": "Developer",
"Age": 32,
"AddressId": 15
}, {
"Id": 3,
"Name": "John",
"Age": 21,
"AddressId": 16
}
]
Notice that NULL values do not show on result. For showing the null values, [INCLUDE_NULL_VALUES] must be added at the end of the query.
SELECT * FROM [TestTable] WHERE id=2 FOR JSON PATH , INCLUDE_NULL_VALUES
output:
[{
"Id": 3,
"Name": "John",
"About": null,
"Age": 21,
"AddressId": 16
}
]
For the query that only return an object, WITHOUT_ARRAY_WRAPPER must be added at the end of query the brackets are remove from the result.
SELECT * FROM [TestTable] WHERE id=2 FOR JSON PATH , INCLUDE_NULL_VALUES , WITHOUT_ARRAY_WRAPPER
output :
{
"Id": 3,
"Name": "John",
"About": null,
"Age": 21,
"AddressId": 16
}
For adding sub query for example the user's contracts or user's family names.
there two way :
1-
SELECT
* ,
ContractList = (SELECT* FROM contract where UserId = 2 FOR JSON PATH)
FROM TestTable FOR JSON PATH
2-
SELECT
* ,
(JSON_QUERY((SELECT* FROM contract WHERE UserId = 2 FOR JSON PATH))) AS ContractList
FROM TestTable FOR JSON PATH
output:
[{
"Id": 3,
"Name": "John",
"About": null,
"Age": 21,
"AddressId": 16 ,
"ContractList" : [{...}, {...}]
}
]
Thank you so much, your answer came to my rescue after a week-long search.
Had to make a few changes to suit my scenario and add quotes around the code
SELECT '[' + STUFF((
SELECT
',['
+ '"'+ CAST(s.Code AS varchar(10)) + '"' + ','
+ COALESCE(''+CAST(COUNT(s.ControlNumber) AS varchar(10)), '')
+ ']'
FROM school s
INNER JOIN [dbo].[Class] cc ON cc.SchoolID = s.SchoolID
INNER JOIN [dbo].[Subject] s ON s.subjectID = cc.subjectID
INNER JOIN [dbo].Marks ms ON s.MarkID = c.CaseStatusID
WHERE ms.Created BETWEEN '2021-04-01 00:00:00' AND '2021-04-07 23:59:59'
AND s.subjectID IN (1, 2, 3, 4, 5, 6, 7, 8, 9)
Group By s.Code
FOR XML PATH(''), TYPE).value('.', 'varchar(MAX)'),1,1,'')
+ ']';
Output
[["za-ec",14],["za-fs",5],["za-gt",3],["za-mp",14],["za-nc",2],["za-nl",8],["za-np",5],["za-nw",6],["za-wc",15]]
SQL 2016 has a new feature which converts data on SQL server to JSON. I am having difficulty in combining array of objects into array of values i.e.,
EXAMPLE -
CREATE TABLE #temp (item_id VARCHAR(256))
INSERT INTO #temp VALUES ('1234'),('5678'),('7890')
SELECT * FROM #temp
--convert to JSON
SELECT (SELECT item_id
FROM #temp
FOR JSON PATH,root('ids'))
RESULT -
{
"ids": [{
"item_id": "1234"
},
{
"item_id": "5678"
},
{
"item_id": "7890"
}]
}
But I want the result as -
"ids": [
"1234",
"5678",
"7890"
]
Can somebody please help me out?
Thanks! The soultion we found is converting into XML first -
SELECT
JSON_QUERY('[' + STUFF(( SELECT ',' + '"' + item_id + '"'
FROM #temp FOR XML PATH('')),1,1,'') + ']' ) ids
FOR JSON PATH , WITHOUT_ARRAY_WRAPPER
Martin!
I believe this is an even simpler way of doing it:
SELECT '"ids": ' +
REPLACE(
REPLACE( (SELECT item_id FROM #temp FOR JSON AUTO),'{"item_id":','' ),
'"}','"' )
declare #temp table (item_id VARCHAR(256))
INSERT INTO #temp VALUES ('1234'),('5678'),('7890')
SELECT * FROM #temp
--convert to JSON
select
json_query(QUOTENAME(STRING_AGG('"' + STRING_ESCAPE(item_id, 'json') + '"', char(44)))) as [json]
from #temp
for json path
When we want to concatenate strings as json array then:
escape string - STRING_ESCAPE
concatenate string with comma separator - STRING_AGG, comma ascii code is 44
add quotation it in brackets - QUOTENAME (without param)
return string (with array of elements) as json - JSON_QUERY
Since arrays of primitive values are valid JSON, it seems strange that a facility for selecting arrays of primitive values isn't built into SQL Server's JSON functionality. (If on the contrary such functionality exists, I at least haven't been able to discover it after quite a bit of searching).
The approach outlined above works as described. But when applied for a field in a larger query, the array of primitives is surrounded with quotes.
E.g., this
DECLARE #BomTable TABLE (ChildNumber dbo.udt_ConMetPartNumber);
INSERT INTO #BomTable (ChildNumber) VALUES (N'101026'), (N'101027');
SELECT N'"Children": ' + REPLACE(REPLACE((SELECT ChildNumber FROM #BomTable FOR JSON PATH), N'{"ChildNumber":', N''), '"}','');
works by producing:
"Children": ["101026,"101027]
But, following the approach above, this:
SELECT
p.PartNumber,
p.Description,
REPLACE(REPLACE((SELECT
ChildNumber
FROM
Part.BillOfMaterials
WHERE
ParentNumber = p.PartNumber
ORDER BY
ChildNumber
FOR
JSON AUTO
), N'{"ChildNumber":', N''), '"}', '"') AS [Children]
FROM
Part.Parts AS p
WHERE
p.PartNumber = N'104444'
FOR
JSON PATH
Produces:
[
{
"PartNumber": "104444",
"Description": "ASSY HUB R-SER DRIV HP10 ABS",
"Children": "[\"101026\",\"101027\",\"102291\",\"103430\",\"103705\",\"104103\"]"
}
]
Where the Children array is wrapped as a string.
This version (building on the others):
correctly escapes an special JSON characters (e.g. quotes)
returns an empty array [] for no data
Requires SQL 2017 or later (due to STRING_AGG):
SELECT
CONCAT('[',
(SELECT STRING_AGG('"' + STRING_ESCAPE(item_id, 'json') + '"', ',')
FROM #temp)
, ']')
Here's a wild idea that may or may not be practical. Recurse over your data set and append things to your JSON arrays using JSON_MODIFY:
with
d (d) as (select * from (values (1),(2),(3),(4)) t (d)),
j (d, j) as (
-- Adapt the recursion to make it dynamic
select 1, json_modify('[]', 'append $', d)
from d
where d = 1
union all
select d.d, json_modify(j, 'append $', d.d)
from d join j on d.d = j.d + 1
)
select *
from j;
I kept it simple for illustration purposes. You'll adapt it to make it dynamic, of course. This produces:
|d |j |
|---|---------|
|1 |[1] |
|2 |[1,2] |
|3 |[1,2,3] |
|4 |[1,2,3,4]|
Could even be used to emulate standard SQL JSON_ARRAYAGG
Most of these solutions are essentially creating a CSV that represents the array contents, and then putting that CSV into the final JSON format. Here's what I use, to avoid XML:
DECLARE #tmp NVARCHAR(MAX) = ''
SELECT #tmp = #tmp + '"' + [item_id] + '",'
FROM #temp -- Defined and populated in the original question
SELECT [ids] = JSON_QUERY((
SELECT CASE
WHEN #tmp IS NULL THEN '[]'
ELSE '[' + SUBSTRING(#tmp, 0, LEN(#tmp)) + ']'
END
))
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
I think the following would be easier in SQL server 2017
select
JSON_QUERY
(
'["' + STRING_AGG(t.item_id,'","') + '"]'
) as ids
from #temp t
for json auto, without_array_wrapper
SQL Server
I have a parameter that contains a comma delimited string:
'abc,def,ghi'
I want to use that string in a IN statement that would take my parameter like this:
select * from tableA where val IN ('abc','def','ghi')
Any ideas on how I would do this?
If using dynamic SQL is an option, this can be executed:
SELECT 'SELECT * FROM tableA WHERE val IN (' +
'''' + REPLACE('abc,def,ghi', ',', ''',''') + ''')'
Basically, the REPLACE() function separates each item by ',' instead of just ,.
The simplest way would be to do something like this:
SELECT *
FROM TableName
WHERE ',' + commaDelimitedString + ',' LIKE '%,' + FieldName + ',%'
But be careful about SQL injection. You might want to parameterize it.
You can use this SQL to 'pivot' a comma-separated string into a table;
DECLARE #badData TABLE (id INT NOT NULL, txt NVARCHAR(max));
INSERT INTO #badData
VALUES (1, 'foo,bar,baz'), (2, NULL);;
-- the idea is to recursively 'pop' a value from the start of the string, splitting it into 'head' and 'tail' components
WITH unpacked (id, head, tail)
AS (
SELECT id, LEFT(txt, CHARINDEX(',', txt + ',') - 1), STUFF(txt, 1, CHARINDEX(',', txt + ','), '')
FROM #badData
UNION ALL
SELECT id, LEFT(tail, CHARINDEX(',', TAIL + ',') - 1), STUFF(tail, 1, CHARINDEX(',', tail+ ','), '')
FROM unpacked
WHERE tail > ''
)
SELECT id, head
FROM unpacked
ORDER BY id
You could stick this result into a common table expression, then write a where clause like
select * from tableA where val IN (select head from unpacked)
heavily plagiarised from https://stackoverflow.com/a/5493616/6722
Many programming languages have a split() function, for example in Ruby
'123,456,789'.split ","
=> ["123", "456", "789"]