skip to Main Content

Snowflake table has a varchar column with following JSON array as value.

[{"$":6394.2,"@":"decisionMetricValue","@id":"Month 1"},{"$":6672.25,"@":"decisionMetricValue","@id":"Month 2"},{"$":5643.05,"@":"decisionMetricValue","@id":"Month 3"},{"$":5564.79,"@":"decisionMetricValue","@id":"Month 4"},{"$":6966.75,"@":"decisionMetricValue","@id":"Month 5"},{"$":7605.15,"@":"decisionMetricValue","@id":"Month 6"}]

Using snowflake sql, I would like to extract data in following format.

Month1,Month2,Month3,Month4,Month5,Month6
6394.2,6672.25,5643.05,5564.79,6966.75,7605.15

I was trying to implement solution https://stackoverflow.com/a/77319223/20535715 , but my json is organized differently.

Thanks.

2

Answers


  1. Chosen as BEST ANSWER

    Had to use use index position differently, it works with a query as blow,

     WITH sample_data AS (
        SELECT
          PARSE_JSON('[
            {"$": 63694.1, "@": "t1"},
            {"$": 63694.2, "@": "t2"},
            {"$": 63694.3, "@": "t3"}
          ]') AS json_data
        )
        SELECT
         json_data[0]."$",
         json_data[1]."$",
         json_data[2]."$"
        FROM sample_data;
    
    

  2. You can try this one. I write it assuming that you may have multiple rows:

    with mytable as (
    select ('[{"$":6394.2,"@":"decisionMetricValue","@id":"Month 1"},{"$":6672.25,"@":"decisionMetricValue","@id":"Month 2"},{"$":5643.05,"@":"decisionMetricValue","@id":"Month 3"},{"$":5564.79,"@":"decisionMetricValue","@id":"Month 4"},{"$":6966.75,"@":"decisionMetricValue","@id":"Month 5"},{"$":7605.15,"@":"decisionMetricValue","@id":"Month 6"}]' ) x
    union all
    select ('[{"$":6394.3,"@":"decisionMetricValue","@id":"Month 1"},{"$":6672.25,"@":"decisionMetricValue","@id":"Month 2"},{"$":5643.05,"@":"decisionMetricValue","@id":"Month 3"},{"$":5564.79,"@":"decisionMetricValue","@id":"Month 4"},{"$":6966.75,"@":"decisionMetricValue","@id":"Month 5"},{"$":7605.15,"@":"decisionMetricValue","@id":"Month 6"}]' ) x
    ),
    flattened as (
    select 
    v.seq row_num,
    get( v.value, '@id' )::VARCHAR colname,
    get( v.value, '$' ) monvalue
    from mytable,
    lateral flatten (  PARSE_JSON(x) )  v
    )
    select * from flattened
    pivot (sum(monvalue) for colname In ('Month 1','Month 2','Month 3','Month 4','Month 5'))
    order by row_num
    ;
    

    This is the result:

    +---------+-----------+-----------+-----------+-----------+-----------+
    | ROW_NUM | 'Month 1' | 'Month 2' | 'Month 3' | 'Month 4' | 'Month 5' |
    +---------+-----------+-----------+-----------+-----------+-----------+
    |       1 |    6394.2 |   6672.25 |   5643.05 |   5564.79 |   6966.75 |
    |       2 |    6394.3 |   6672.25 |   5643.05 |   5564.79 |   6966.75 |
    +---------+-----------+-----------+-----------+-----------+-----------+
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search