0

I have a JSON like this to process in SQL

{"RowIndex":[1,2], "Data":["a","b"]}

and i want to extract the data to show that as a table like this

RowIndex    Data
  1           a
  2           b

I understand that i have to use OPENJSON, JSON_QUERY or JSON_VALUE but i cannot find a way to get what I want that not implies to write a query with many join like

select  C1.value as RowIndex,
        C2.value as Data,
From (select [key], value from OPENJSON(JSON_QUERY(@jsonstring, '$.RowIndex'))) C1 
inner join (select [key], value from OPENJSON(JSON_QUERY(@jsonstring, '$.Data'))) C2 on C1.[key] = C2.[key] 

Because if the arrays in the JSON grow the query will be unmaintenable and slow

Sethlans
  • 407
  • 1
  • 5
  • 20

1 Answers1

1

One method, using a "couple" of OPENJSON clauses:

DECLARE @JSON nvarchar(MAX) = N'{"RowIndex":[1,2], "Data":["a","b"]}';

SELECT RI.[value] AS RowIndex,
       D.[value] AS Data
FROM OPENJSON(@JSON)
     WITH (RowIndex nvarchar(MAX) AS JSON,
           Data nvarchar(MAX) AS JSON) J
     CROSS APPLY OPENJSON(RowIndex) RI
     CROSS APPLY OPENJSON(Data) D
WHERE RI.[key] = D.[key];

To elaborate on my comments though, it seems like you should be fixing the JSON design and have something like this:

[
    {
        "RowIndex": "1",
        "Data": "a",
        "Number": "1"
    },
    {
        "RowIndex": "2",
        "Data": "b",
        "Number": "3"
    }
]

Which can be far more easily queried:

DECLARE @JSON nvarchar(MAX) = N'[
    {
        "RowIndex": "1",
        "Data": "a",
        "Number": "1"
    },
    {
        "RowIndex": "2",
        "Data": "b",
        "Number": "3"
    }
]';

SELECT *
FROM OPENJSON(@JSON)
     WITH (RowIndex int,
           Data char(1),
           Number int) OJ;
Thom A
  • 88,727
  • 11
  • 45
  • 75
  • If I understand well, if I have 3 arrays there will be 3 OPENJSON and so on – Sethlans Jul 29 '20 at 15:11
  • 1
    Correct, @MattiaGiacone , and more clauses in your `WHERE`. If that is the case, however, then it seems the real problem is the JSON and your JSON should look more like this (added an extra node, `Number`): `[{"RowIndex": "1","Data": "a","Number":"1"},{"RowIndex": "2","Data": "b","Number":"3"}]` – Thom A Jul 29 '20 at 15:12
  • It will be better if I can generate the JSON like `{[{ "RowIndex":0, "Data":"a" },{ "RowIndex":1, "Data":"b" }]}` to perform a query like `SELECT JSON_VALUE([value], '$.RowIndex') AS RowIndex, JSON_VALUE([value], '$.Data') AS Data, FROM (SELECT [key],[value],[type] FROM OPENJSON(@jsonstring) )` – Sethlans Jul 29 '20 at 15:19
  • 1
    Why "spam" `JSON_VALUE` @MattiaGiacone? It's slower (I confirmed this earlier today in [another answer](https://stackoverflow.com/a/63154238/2029983)). – Thom A Jul 29 '20 at 15:23
  • yes that's better. The real Json has 12 array and for 250 element with the 12 cross apply it takes around 1 second. But if i create the json in the other way the query is almost instantaneous – Sethlans Jul 29 '20 at 15:38
  • I've updated my answer for if you improve your JSON, @MattiaGiacone . – Thom A Jul 29 '20 at 15:48