簡體   English   中英

oracle sql 中的 JSON_TABLE 未捕獲的嵌套 json 數據

[英]Nested json data not captured by JSON_TABLE in oracle sql

我正在使用 Oracle 12c(12.2) 讀取表中的 json 數據。

SELECT        jt.name,
jt.employee_id, 
jt.company    
FROM JSON_TABLE ( BFILENAME ('DB_DIR', 'vv.json')

我在 json output 中嵌套了數據。 嵌套數據中的 key:value 以記錄的值"past_work": "NA" 對於它下面的其他許多記錄,具有實際值,例如

"past_work": [{ "company": "XXXXX",   "title": "XXXX"}]

但是因為完成的第一條記錄具有值以及開始和結束括號 [],oracle 沒有捕獲下面的記錄嵌套值。 知道如何捕獲以下記錄嗎?

示例:如下所示的實際數據

  SELECT
      jt.company,
      jt.title
    FROM
      JSON_TABLE(
        '{
           "employee_data": [
             { "employee_id": "111",
               "past_work": "N/A"
             },
             { "employee_id": "222",
               "past_work": [
                 {"company": "XXXXX", "title": "XXXX"},
                 {"company": "YYYYY", "title": "YYYY"}
               ]
             },
             { "employee_id": "333",
               "past_work": [
                 {"company": "XXXXX", "title": "XXXX"},
                 {"company": "YYYYY", "title": "YYYY"}
                ]
             }
           ]
         }',
        '$.past_work[*]'
          COLUMNS (
            company VARCHAR2(100) PATH '$.company',
            title   VARCHAR2(100) PATH '$.title'
          )
      )
        AS jt

現在,當我執行上述語句時,我得到 null 用於 emplyee_id 333 及以下的公司價值。

謝謝

如果past_work應該是一個過去(company, title)對的數組,那么編碼“no history”的正確方法是不要使用像"N/A"這樣的字符串值,而是應該使用一個空數組,正如我在下面的代碼中所示。 如果你按照自己的方式去做,你仍然可以提取數據,但它會異常混亂。 如果您使用JSON,請正確使用。

另外,你說你想提取公司和頭銜。 就這些? 這是沒有意義的。 相反,您可能希望提取每個員工的員工 ID 以及工作歷史。 在工作歷史中,我添加了一個“for ordinality”列(以顯示哪個公司是第一個,哪個是第二個等)如果您不需要它,只需將其省略即可。

要訪問嵌套列,您必須使用columns規范中的nested子句。

select employee_id, ord, company, title
from   json_table(
        '{
           "employee_data": [
             { "employee_id": "111",
               "past_work": [ ]
             },
             { "employee_id": "222",
               "past_work": [
                 {"company": "XXXXX", "title": "XXXX"},
                 {"company": "YYYYY", "title": "YYYY"}
               ]
             },
             { "employee_id": "333",
               "past_work": [
                 {"company": "XXXXX", "title": "XXXX"},
                 {"company": "YYYYY", "title": "YYYY"}
                ]
             }
           ]
         }',   '$.employee_data[*]'
               columns ( 
                         employee_id varchar2(10) path '$.employee_id',
                           nested path '$.past_work[*]'
                               columns (
                                         ord     for ordinality,
                                         company varchar2(10) path '$.company',
                                         title   varchar2(10) path '$.title'
                                       )
                       )
       ) jt
order by employee_id, ord;

Output:

EMPLOYEE_ID ORD COMPANY TITLE
----------- --- ------- -----
111                          
222           1 XXXXX   XXXX 
222           2 YYYYY   YYYY 
333           1 XXXXX   XXXX 
333           2 YYYYY   YYYY 

首先,json 代碼段格式不正確,它必須被{}包圍才能被解析為 json object...

  • {"past_work": [{ "company": "XXXXX", "title": "XXXX"}]}

然后,您可以告訴 json 解析器您要從past_work元素中提取行...

  • JSON_TABLE(<yourJsonString>, '$.past_work[*]')

[*]告訴解析器past_work是一個數組,並將該數組處理為 json 對象的行,而不是將整個數組作為單個 json object 返回。

這給出了類似...

SELECT
  jt.company,
  jt.title
FROM
  JSON_TABLE(
    '{
        "past_work": [
            {"company": "XXXXX", "title": "XXXX"},
            {"company": "YYYYY", "title": "YYYY"}
        ]
     }',
    '$.past_work[*]'
      COLUMNS (
        company VARCHAR2(100) PATH '$.company',
        title   VARCHAR2(100) PATH '$.title'
      )
  )
    AS jt

db<>小提琴演示


有關更多詳細信息,我建議閱讀文檔:


編輯:更新的示例,幾乎是文檔中的復制和粘貼

  • 請閱讀文檔!

SELECT
  jt.*
FROM
  JSON_TABLE(
    '{
        "XX_data":[
          {
            "employee_id": "E1",
            "full_name":   "E1  Admin",
            "past_work":   "N/A"
          },
          {
            "employee_id": "E2",
            "full_name":   "E2  Admin",
            "past_work": [
              {"company": "E2 PW1 C", "title": "E2 PW1 T"},
              {"company": "E2 PW2 C", "title": "E2 PW2 T"},
            ]
          },
        ]
     }',
    '$.XX_data[*]'
      COLUMNS (
        employee_id VARCHAR2(100) PATH '$.employee_id',
        full_name   VARCHAR2(100) PATH '$.full_name',
        past_work   VARCHAR2(100) PATH '$.past_work',
        NESTED PATH '$.past_work[*]'
          COLUMNS (
            past_work_company VARCHAR2(100) PATH '$.company',
            past_work_title   VARCHAR2(100) PATH '$.title'
          )
      )
  )
    AS jt

另一個 db<>fiddle 演示

感謝大家的評論。 已要求產品團隊提供正確格式的數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM