Reputation: 23
I use SQL Server and I need to move "setting0"
and "setting1"
from one JSON value into a new JSON value in a new record;
Here is the table structure:
userId | setting type | settings
-------+--------------+-----------------------------------------------
id0 | type0 | {"setting0": 0, "setting1": 1, "setting2": 2, "...", "setting100": 100}
and I need to get this result:
userId | setting type | settings
-------+--------------+---------------------------------
id0 | type0 | {"setting2": 2, "...", "setting100": 100}
id0 | type1 | {"setting0": 0, "setting1": 1}
Update:
There are a lot of settings in JSON value with type0
and due to business logic I need to separate only setting0
and setting1
from type0
and move it to type1
.
Many thanks in advance
Upvotes: 2
Views: 325
Reputation: 29993
Another possible approach is to use VALUES
table value constructor and:
OPENJSON()
with explicit schema to extract the $.setting0
and $.setting1
key\value pairs from the existing JSON data with the appropriate data types and FOR JSON
to output the extracted values as JSON.JSON_MODIFY()
with NULL
as value to delete the $.setting0
and $.setting1
keys.Table:
CREATE TABLE Data (
userID varchar(3),
settingType varchar(5),
settings varchar(1000)
)
INSERT INTO Data (userID, settingType, settings)
VALUES
('id0', 'type0', '{"setting0":0,"setting1":1,"setting2":2,"setting3":3}'),
('id1', 'type0', '{"setting0":0,"setting1":1,"setting2":2,"setting3":3,"setting4":4}')
Statement:
SELECT d.userID, v.settingType, v.settings
FROM Data d
CROSS APPLY (VALUES
-- Existing row
(
d.settingType,
JSON_MODIFY(JSON_MODIFY(d.settings, '$.setting0', NULL), '$.setting1', NULL)
),
-- New row
(
'type1',
(
SELECT setting0, setting1
FROM OPENJSON(d.settings) WITH (
setting0 int '$.setting0',
setting1 int '$.setting1'
)
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
)
)
) v (settingType, settings)
Result:
userID settingType settings
-----------------------------------------------------------
id0 type0 {"setting2":2,"setting3":3}
id0 type1 {"setting0":0,"setting1":1}
id1 type0 {"setting2":2,"setting3":3,"setting4":4}
id1 type1 {"setting0":0,"setting1":1}
Upvotes: 2
Reputation: 6015
The following returns the correct output. First, for each userID it returns 'setting2' (if it exists) as JSON. Second, for each userID it modifies the JSON to remove 'setting2' (if it exists). Something like this
Data
drop table if exists #JsonSettings;
go
create table #JsonSettings(
userID varchar(12) not null,
settingType varchar(12) not null,
settings nvarchar(max));
insert #JsonSettings(userID, settingType, settings) values
('id0', 'type0', N'{"setting0": 0, "setting1": 1, "setting2": 2}'),
('id2', 'type0', N'{"setting0": 0, "setting1": 1, "setting2": 2, "setting3": 3}');
Query
select distinct userId, settingType,
(select json_value(settings, '$.setting2') setting2
for json path, without_array_wrapper) settings
from #JsonSettings js
cross apply openjson(js.settings) oj
where oj.[key]=N'setting2'
union all
select distinct userId, settingType,
json_modify(js.settings,'$.setting2', null) settings
from #JsonSettings js
cross apply openjson(js.settings) oj
where oj.[key]=N'setting2'
order by 1, 3 desc;
Output
userId settingType settings
id0 type0 {"setting2":"2"}
id0 type0 {"setting0": 0, "setting1": 1}
id2 type0 {"setting2":"2"}
id2 type0 {"setting0": 0, "setting1": 1, "setting3": 3}
Upvotes: 0
Reputation: 675
You have to read the table row you want to get the data from, remove the code you want to move, update the row and insert the removed data into a new row.
Note that you're not getting any detailed information about how to do this if you're not giving more detailed information about your problem.
setting_type
?Upvotes: 0