3

I have a VARCHAR(16777216) column in a snowflake database table, that is structured as an array with JSON in it.

An example of a row in the column: [ {"Name":"John", "Last Name": "Doe"}, {"Name":"Frank", "Last Name": "Doe"}]

How do I use sql to select all of the Last Names in each row?

Please note, this is a VARCHAR COLUMN.

1
  • Since the column definition is VARCHAR you have no direct way to process the JSON via SQL. Depending on what relational database you are using there are explicit JSON types that you could of defined your column as, with respective queries to process the records. Example in MySQL: dev.mysql.com/doc/refman/8.0/en/json.html So in your case, since your column is VARCHAR you will need to extract the entire record and process the JSON pragmatically via whatever programming language you are using. I personally would prefer doing this in all cases. Commented Jan 10, 2020 at 15:48

1 Answer 1

3

You can flatten the JSON array and then extract the Last Name field like this:

WITH SampleData AS (
  SELECT '[ {"Name":"John", "Last Name": "Doe"}, {"Name":"Frank", "Last Name": "Doe"}]' AS text
)
SELECT json_object.value:"Last Name" AS last_name
FROM SampleData, LATERAL FLATTEN (input => PARSE_JSON(text)) json_object;

This returns:

LAST_NAME
"Doe"
"Doe"

In the query, the LATERAL FLATTEN part is what indicates to return a row for each entry in the text after parsing it as JSON, and then in the SELECT list, json_object.value returns the value for this row, and :"Last Name" returns the field named Last Name from it. The WITH SampleData (...) part just creates some inline data with a VARCHAR column named text.

If you want a single row for each input row, where the last names are in an array, you can use a query of this form:

WITH SampleData AS (
  SELECT '[ {"Name":"John", "Last Name": "Doe"}, {"Name":"Frank", "Last Name": "Doe"}]' AS text
)
SELECT ARRAY_AGG(json_object.value:"Last Name") AS last_names
FROM SampleData, LATERAL FLATTEN (input => PARSE_JSON(text)) json_object
GROUP BY text;

This returns:

LAST_NAMES
[    "Doe",    "Doe"  ]
Sign up to request clarification or add additional context in comments.

5 Comments

This is pretty cool, though for this line SELECT PARSE_JSON('[ {"Name":"John", "Last Name": "Doe"}, {"Name":"Frank", "Last Name": "Doe"}]') Can you have an inner select to populate the json data for the PARSE_JSON() function directly from the table, because you are manually adding the values where in the question presented he has the values stored in a column. So what I am seeing here is a way to PARSE a JSON object using SQL, in a similar manner that can be done pragmatically via any language. There seems to be a small gap with what was shown here (unless I am missing something)
Right, if you have a VARIANT column, as it sounds like the OP does, you would just select from it directly rather than using PARSE_JSON.
Hi, so I do not have a Json column, it is a VarChar Column.
The OP has a VARCHAR column (basic string) not a VARIANT column. But with your provided solution as long as he can do an inner select within the PARSE_JSON function or find a way to do the select and pass the value as a variable to the PARSE_JSON() function it will work.
Oh, that's right. You don't need an inner select...see the updated answer.

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.