0

My table structure is as below.

I want to return the data column but joined together as a JSON where type = 1 and order by the time column. I used STRING_AGG(), but its not what I want since I need to serialize this in the other side.

 | id | type |data                             | time              |
 | ---|----- | ------------------------------- |-------------------|
 | 1  | 1    |[{"X":55,"Y":97}]                |2022-03-02 17:20:21|
 | 2  | 1    |[{"X":3,"Y":6},{"X":39,"Y":9}]   |2022-03-02 17:20:25|
 | 3  | 5    |[{"X":9,"Y":9},{"X":33,"Y":1}]   |2022-03-02 17:20:29|

Basically I need to return [{"X":55,"Y":97},{"X":3,"Y":6},{"X":39,"Y":9}]

6
  • im using sqlserver Commented Mar 2, 2022 at 7:48
  • What you describe has nothing to do with JOINs. Frankly, it looks like the table needs a drastic redesign. What are those values and why aren't they stored in a separate table? Or as a geometry type? If this is a MULTIPOINT or LINESTRING, you could use UnionAggregate to combine the points Commented Mar 2, 2022 at 8:00
  • If you really have to deal with JSON arrays, you first need to extract the values with OPENJSON then combine the result back into a JSON string with FOR JSON Commented Mar 2, 2022 at 8:02
  • @PanagiotisKanavos this is data from a graph. they are read over a long period of time and we save data every one second. for every save im creating a new row. (that can have one - 20 datapoints) . but later on , i need to get all the data points for a given type. Commented Mar 2, 2022 at 21:26
  • That doesn't change any of the comments. You can store this as a MULTIPOINT in a geometry column and even add spatial indexes if needed. If you want to keep using JSON, you'll have to parse the content and generate a new JSON string as Zhorov shows Commented Mar 3, 2022 at 8:27

1 Answer 1

1

A possible approach is to parse the stored data as JSON, filter and order the returned data, and build the expected data as JSON:

Table:

SELECT *
INTO Data 
FROM (VALUES
   (1, 1, '[{"X":55,"Y":97}]',              CONVERT(datetime2(0), '2022-03-02T17:20:21')),
   (2, 1, '[{"X":3,"Y":6},{"X":39,"Y":9}]', CONVERT(datetime2(0), '2022-03-02T17:20:25')),
   (3, 5, '[{"X":9,"Y":9},{"X":33,"Y":1}]', CONVERT(datetime2(0), '2022-03-02T17:20:29'))
) d (id, [type], data, time)

Statement:

SELECT 
   X = CONVERT(int, JSON_VALUE(j.[value], '$.X')),
   Y = CONVERT(int, JSON_VALUE(j.[value], '$.Y'))
FROM Data d
CROSS APPLY OPENJSON(d.data) j
WHERE d.type = 1
ORDER BY d.time, CONVERT(int, j.[key])
FOR JSON AUTO

Result:

[{"X":55,"Y":97},{"X":3,"Y":6},{"X":39,"Y":9}]
Sign up to request clarification or add additional context in comments.

2 Comments

May i know what does , CONVERT(int, j.[key]) this part do ?
OPENJSON with default schema returns a table with columns key, value and type and when the parsed JSON is a JSON array, the key column holds a 0-based index of the element in the specified array as an nvarchar(4000) value. CONVERT(int, j.[key]) simply returns the JSON array items in the original order.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.