I have the following table with JSON collections:
| ID | SliderJson |
|---|---|
| 1 | [{"Slider":11, "Value":2},{"Slider":4, "Value":3}] |
| 2 | |
| 3 | [{"Slider":11, "Value":4},{"Slider":4, "Value":3},{"Slider":25, "Value":3},{"Slider":2, "Value":4},{"Slider":5, "Value":3}] |
As can be see in the example not all records have a value, and those that have the length of the array vary (by a maximum of 9 items). Ideally I would like to create a column for each slider that contains its entry value, but there are about 400 million records and about 80 different sliders.
So I would be happy to create a columns only for certain sliders, say 4 and 5 and get the following table.
| ID | SliderJson | 4 | 5 |
|---|---|---|---|
| 1 | [{"Slider":11, "Value":2},{"Slider":4, "Value":3}] | 3 | NULL |
| 2 | NULL | NULL | |
| 3 | [{"Slider":11, "Value":4},{"Slider":4, "Value":3},{"Slider":25, "Value":3},{"Slider":2, "Value":4},{"Slider":5, "Value":3}] | 3 | 3 |
Or alternatively create a table that will extract the json to the columns in the following way:
| ID | SliderJson | slider1 | value1 | slider2 | value2 | slider3 | value3 |
|---|---|---|---|---|---|---|---|
| 1 | [{"Slider":11, "Value":2},{"Slider":4, "Value":3}] | 11 | 2 | 4 | 3 | NULL | NULL |
| 2 | NULL | NULL | NULL | NULL | NULL | NULL | |
| 3 | [{"Slider":11, "Value":4},{"Slider":4, "Value":3},{"Slider":25, "Value":3},{"Slider":2, "Value":4},{"Slider":5, "Value":3}] | 11 | 4 | 4 | 3 | 25 | 3 |
Both options are good and working for me, the only consideration is efficiency because as mentioned there are a millions of records (and maybe there are other options that are preferred and I have not thought about). It also important that each record be associated with its original id.
So far I tried the following proceeder, however even when I execute it on very small amount of rows (only 100) it took hours, so I guess something wrong.
DECLARE @NOTE_ID uniqueidentifier
DECLARE @USER_ID uniqueidentifier
DECLARE @SINGEL_SLIDER NVARCHAR(MAX)
DECLARE SLIDER_CURSOR CURSOR FOR SELECT [NoteID],[UserID],[SliderJSON] FROM [dbo].[SmallData]
OPEN SLIDER_CURSOR
FETCH NEXT FROM SLIDER_CURSOR INTO @NOTE_ID, @USER_ID, @SINGEL_SLIDER
WHILE @@FETCH_STATUS = 0
BEGIN
IF len(@SINGEL_SLIDER)>1
BEGIN
IF OBJECT_ID('tempdb..#TMP') IS NOT NULL
DROP TABLE #TMP
SELECT *
INTO #TMP
FROM OPENJSON(@SINGEL_SLIDER)
DECLARE @SLIDER_VALUE NVARCHAR(MAX)
DECLARE SLIDER_VALUE_CURSOR CURSOR FOR SELECT [value] FROM #TMP
OPEN SLIDER_VALUE_CURSOR
FETCH NEXT FROM SLIDER_VALUE_CURSOR INTO @SLIDER_VALUE
WHILE @@FETCH_STATUS = 0
BEGIN
IF OBJECT_ID('tempdb..#TMP1') IS NOT NULL
DROP TABLE #TMP1
SELECT *
INTO #TMP1
FROM OPENJSON(@SLIDER_VALUE)
DECLARE @SLIDER_ID NVARCHAR(100)
DECLARE @SLIDER_OPTION_ID NVARCHAR(100)
SET @SLIDER_ID = (SELECT [value] FROM #TMP1 WHERE [key] = 'Slider')
SET @SLIDER_OPTION_ID = (SELECT [value] FROM #TMP1 WHERE [key] = 'Value')
IF @SLIDER_ID = 4
BEGIN
UPDATE [dbo].[SmallData]
SET [4] = @SLIDER_OPTION_ID
WHERE [NoteID] = @NOTE_ID
END
ELSE IF @SLIDER_ID = 7
BEGIN
UPDATE [dbo].[SmallData]
SET [7] = @SLIDER_OPTION_ID
WHERE [NoteID] = @NOTE_ID
END
ELSE IF @SLIDER_ID = 1
BEGIN
UPDATE [dbo].[SmallData]
SET [1] = @SLIDER_OPTION_ID
WHERE [NoteID] = @NOTE_ID
END
ELSE IF @SLIDER_ID = 10
BEGIN
UPDATE [dbo].[SmallData]
SET [10] = @SLIDER_OPTION_ID
WHERE [NoteID] = @NOTE_ID
END
ELSE IF @SLIDER_ID = 43
BEGIN
UPDATE [dbo].[SmallData]
SET [43] = @SLIDER_OPTION_ID
WHERE [NoteID] = @NOTE_ID
END
ELSE IF @SLIDER_ID = 15
BEGIN
UPDATE [dbo].[SmallData]
SET [15] = @SLIDER_OPTION_ID
WHERE [NoteID] = @NOTE_ID
END
ELSE IF @SLIDER_ID = 18
BEGIN
UPDATE [dbo].[SmallData]
SET [18] = @SLIDER_OPTION_ID
WHERE [NoteID] = @NOTE_ID
END
END
FETCH NEXT FROM SLIDER_VALUE_CURSOR INTO @SLIDER_VALUE
END
CLOSE SLIDER_VALUE_CURSOR
DEALLOCATE SLIDER_VALUE_CURSOR
FETCH NEXT FROM SLIDER_CURSOR INTO @NOTE_ID, @USER_ID, @SINGEL_SLIDER
END
CLOSE SLIDER_CURSOR
DEALLOCATE SLIDER_CURSOR
I would appreciate any help on this subject.
OPENJSON? what about the functionalitu didn't you understand?