postgres jsonb返回节点的任何后代

时间:2018-01-31 00:53:56

标签: postgresql jsonb

我试图解析以下JSON以返回所有产品代码(PL,FG,KK)及其rrp值。我想在没有硬编码包含产品代码节点(PL,FG,KK)的路径的情况下这样做 - 任何人都可以告诉我如何获取给定节点的任何后代,即xpath有//概念要做此

{  "catalog": [
    {
      "product": {
        "PL": {
          "price": {
            "rrp": {
              "value": 232.75
            }
          }
        }
      },
      "desc": "d_pl"
    },
    {
      "product": {
        "FG": {
          "price": {
            "rrp": {
              "value": 132
            }
          }
        }
      },
      "desc": "d_fg"
    },
    {
      "product": {
        "KK": {
          "price": {
            "rrp": {
              "value": 36.15
            }
          }
        }
      },
      "desc": "d_kk"
    }
  ]
}

我想要获得的输出是



<table style="width:20%">
  <tr>
    <th>Product_Code</th>
    <th>Desc</th> 
    <th>RRP</th>
  </tr>
  <tr>
    <td>PL</td>
    <td>d_pl</td> 
    <td>232.75</td>
  </tr>
<tr>
    <td>FG</td>
    <td>d_fg</td> 
    <td>132.00</td>
  </tr>
<tr>
    <td>KK</td>
    <td>d_kk</td> 
    <td>36.15</td>
  </tr>
</table>
&#13;
&#13;
&#13;

到目前为止我尝试的代码是

WITH t(content) AS ( VALUES
  ('{"catalog": [    
  {      "product": {        "PL": {          "price": {            "rrp": {                  "value": 232.75            }          }        }      },      "desc": "d_pl"        },    
  {      "product": {        "FG": {          "price": {            "rrp": {                  "value": 132            }          }        }      },      "desc": "d_fg"    },    
  {      "product": {        "KK": {          "price": {            "rrp": {                  "value": 36.15            }          }        }      },      "desc": "d_kk"    }      ]}'::JSONB)
)
SELECT
  jsonb_object_keys(jsonb_array_elements(t.content -> 'catalog') ->     'product') AS product_code,
  jsonb_array_elements(t.content -> 'catalog') ->> 'desc' as Descr,
  jsonb_array_elements(t.content -> 'catalog') -> 'product' -> 'PL' ->     'price' -> 'rrp' -> 'value' as rrp  -- how do i define any node rather than hardcoded PL 
FROM t
;

但是这显然没有返回所有记录,因为它硬编码了PL。

提前致谢

1 个答案:

答案 0 :(得分:0)

我找到了解决问题的方法,但这可能不是最优雅的方法

WITH t(myjson) AS ( VALUES
  ('{"catalog": [    
  {      "product": {        "PL": {          "price": {            "rrp": {                  "value": 232.75            }          }        }      },      "desc": "d_pl"        },    
  {      "product": {        "FG": {          "price": {            "rrp": {                  "value": 132            }          }        }      },      "desc": "d_fg"    },    
  {      "product": {        "KK": {          "price": {            "rrp": {                  "value": 36.15            }          }        }      },      "desc": "d_kk"    }      ]}'::JSONB)
)
SELECT
    product.key as product_code,
    products ->> 'desc' as descr,
    inner_price.value ->'rrp' ->> 'value' as rrp
FROM t,
     jsonb_array_elements(t.myjson -> 'catalog') products,
     jsonb_each(products -> 'product') product,
     jsonb_each(product.value) inner_price
WHERE
  inner_price.key = 'price'
;