skip to Main Content

The tables in the query are not designed or controlled by me. Please don’t tell me to change the table structure because it is outside my scope.
using
"PostgreSQL 11.16 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 7.3.1 20180712 (Red Hat 7.3.1-12), 64-bit"

This is a snippet of the table structure. All json is stored as character varying. This is one column in the table. For this exercise, just call the table "ThisTable" and the column "Brands".

[
    {
        "site": "https://brand.map.com/cur",
        "type": {
            "coding": [
                {
                    "code": "gee",
                    "display": "Green Field",
                    "site": "http://ag.org/clear/latest/green-fld/Coding/GrType",
                    "version": "1.0.0"
                }
            ]
        },
        "value": "101B_xx20048TS5M_113"
    },
    {
        "site": "https://brand.map.com/cur",
        "type": {
            "coding": [
                {
                    "code": "gee",
                    "display": "Green Field",
                    "site": "http://ag.org/clear/latest/green-fld/Coding/GrType",
                    "version": "1.0.0"
                }
            ]
        },
        "value": "50499_PR2051TGY_211"
    },
    {
        "site": "https://brand.map.com/cur",
        "type": {
            "coding": [
                {
                    "code": "gee",
                    "display": "Green Field",
                    "site": "http://ag.org/clear/latest/green-fld/Coding/GrType",
                    "version": "1.0.0"
                }
            ]
        },
        "value": "931002492_GHJ120044VDA22_321"
    },
    {
        "site": "https://brand.map.com/cur",
        "type": {
            "coding": [
                {
                    "code": "gee",
                    "display": "Green Field",
                    "site": "http://ag.org/clear/latest/green-fld/Coding/GrType",
                    "version": "1.0.0"
                }
            ]
        },
        "value": "4023451_JK49880RWD_521"
    },
    {
        "site": "https://brand.map.com/cur",
        "type": {
            "coding": [
                {
                    "code": "gee",
                    "display": "Green Field",
                    "site": "http://ag.org/clear/latest/green-fld/Coding/GrType",
                    "version": "1.0.0"
                }
            ]
        },
        "value": "71093129_PR3225TGY_211"
    },
    {
        "site": "https://brand.map.com/cur",
        "type": {
            "coding": [
                {
                    "code": "gee",
                    "display": "Green Field",
                    "site": "http://ag.org/clear/latest/green-fld/Coding/GrType",
                    "version": "1.0.0"
                }
            ]
        },
        "value": "71093419_PR3225TGY_211"
    }
]

the goal is to find a particular site (upper level in the nesting- example "https://brand.map.com/cur")
for a particular code and system in the nested type/coding structure. (example is code "gee" for site "http://ag.org/clear/latest/green-fld/Coding/GrType" for the Brands column.

this could be used in either a select or a where clause (e.g. need to display it and/or use it as selection criteria)

I can break out the Brands column and get the type and/or coding, but I am failing to see how to break out the coding array. I’ve been using a cross join. This shows a way to break out the details but fails if I try to add the site type array.

from ThisTable TT
cross join jsonb_array_elements(TT.Brands::jsonb) as ttb(site_arr)
--cross join jsonb_array_elements(ttb.site_arr->>'type') as ttbs(sitetype_arr) 

I can work around this but mostly want to understand. This is the selection I need to make (I think) but I can’t select type or coding to extract this and then cross join.
I’m not sure if unnest is a better option. I could not get json_path_query to work in this case.

SELECT brandtype->>'code' as brand_type_code
FROM jsonb_array_elements('[
                {
                    "code": "gee",
                    "display": "Green Field",
                    "site": "http://ag.org/clear/latest/green-fld/Coding/GrType",
                    "version": "1.0.0"
                }
            ]') as brandtype

2

Answers


  1. Maybe this will helped you. If you need anything else, let me, I will explain or help.

    with table1 as (
    select 
    '[
        {
            "site": "https://brand.map.com/cur",
            "type": {
                "coding": [
                    {
                        "code": "gee",
                        "display": "Green Field",
                        "site": "http://ag.org/clear/latest/green-fld/Coding/GrType",
                        "version": "1.0.0"
                    }
                ]
            },
            "value": "101B_xx20048TS5M_113"
        },
        {
            "site": "https://brand.map.com/cur",
            "type": {
                "coding": [
                    {
                        "code": "gee",
                        "display": "Green Field",
                        "site": "http://ag.org/clear/latest/green-fld/Coding/GrType",
                        "version": "1.0.0"
                    }
                ]
            },
            "value": "50499_PR2051TGY_211"
        },
        {
            "site": "https://brand.map.com/cur",
            "type": {
                "coding": [
                    {
                        "code": "gee",
                        "display": "Green Field",
                        "site": "http://ag.org/clear/latest/green-fld/Coding/GrType",
                        "version": "1.0.0"
                    }
                ]
            },
            "value": "931002492_GHJ120044VDA22_321"
        },
        {
            "site": "https://brand.map.com/cur",
            "type": {
                "coding": [
                    {
                        "code": "gee",
                        "display": "Green Field",
                        "site": "http://ag.org/clear/latest/green-fld/Coding/GrType",
                        "version": "1.0.0"
                    }
                ]
            },
            "value": "4023451_JK49880RWD_521"
        },
        {
            "site": "https://brand.map.com/cur",
            "type": {
                "coding": [
                    {
                        "code": "gee",
                        "display": "Green Field",
                        "site": "http://ag.org/clear/latest/green-fld/Coding/GrType",
                        "version": "1.0.0"
                    }
                ]
            },
            "value": "71093129_PR3225TGY_211"
        },
        {
            "site": "https://brand.map.com/cur",
            "type": {
                "coding": [
                    {
                        "code": "gee",
                        "display": "Green Field",
                        "site": "http://ag.org/clear/latest/green-fld/Coding/GrType",
                        "version": "1.0.0"
                    }
                ]
            },
            "value": "71093419_PR3225TGY_211"
        }
    ]'::jsonb as datajson)
    select 
        table2->>'site', 
        table2->>'value', 
        table2->'type'->'coding'->0->>'code', 
        table2->'type'->'coding'->0->>'display', 
        table2->'type'->'coding'->0->>'version' 
    from table1
    cross join jsonb_array_elements(table1.datajson) as table2 
    
    Result: 
    https://brand.map.com/cur   101B_xx20048TS5M_113            gee     Green Field     1.0.0
    https://brand.map.com/cur   50499_PR2051TGY_211             gee     Green Field     1.0.0
    https://brand.map.com/cur   931002492_GHJ120044VDA22_321    gee     Green Field     1.0.0
    https://brand.map.com/cur   4023451_JK49880RWD_521          gee     Green Field     1.0.0
    https://brand.map.com/cur   71093129_PR3225TGY_211          gee     Green Field     1.0.0
    https://brand.map.com/cur   71093419_PR3225TGY_211          gee     Green Field     1.0.0
    
    Login or Signup to reply.
  2. If I recapitulate what you are doing by filling in the missing pieces and then uncommenting the commented out jsonb_array_elements I get this error:

    ERROR:  function jsonb_array_elements(text) does not exist
    LINE 3: cross join jsonb_array_elements(ttb.site_arr->>'type') as tt...
    

    (But you should show the error yourself, not make us re-discover it.) And the reason for this error is that ->> yields text, not jsonb. If I switch it to -> to preserve the type as jsonb, then I get a different error:

    ERROR:  cannot extract elements from an object
    

    Which is because ->'type' on your data yields an object, not an array. You can pull the array out of that object by adding one more level of referencing, so:

    select sitetype_arr from ThisTable TT
    cross join jsonb_array_elements(TT.Brands::jsonb) as ttb(site_arr)
    cross join jsonb_array_elements(ttb.site_arr->'type'->'coding') as ttbs(sitetype_arr);
    

    Now this does work. It yields the same thing 6 times, but that is because your data just has the same thing repeated 6 times; there is nothing we can do about your data being silly.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search