Oracle 12c JSON

时间:2018-08-30 13:15:28

标签: json oracle oracle12c

我有两个桌子。员工和贷款。后者对Employee具有外国参考。一名员工可以拥有多笔贷款。在我的简化示例中,我们只有一种类型的贷款“ creditLoan”。

我希望将每个员工的贷款安排成JSON格式,如下所示:

{
    "employeeID": "10001",
    "instID": "123456789",
    "loans": [
       {
          "creditLoan": 
             {
               "id":"123",
               "amount":"-20000"
             }
       },
       {
          "creditLoan": 
             {
               "id":"234",
               "amount":"-30000"
             }
       }       
    ]
}

到目前为止,我只涉及到这一点:

SELECT JSON_OBJECT(
          'employeeID' VALUE E.ID, 
          'instID' VALUE '123456789',
          'loans' VALUE (
               SELECT JSON_ARRAYAGG(
                    JSON_OBJECT(
                         'creditLoan' VALUE  (
                              SELECT JSON_ARRAYAGG (
                                   JSON_OBJECT(
                                        KEY 'id' VALUE L.ID,  
                                        KEY 'amount' VALUE L.AMOUNT)
                                   )

                               FROM LOANS L WHERE L.EMP_ID=E.ID)))
          FROM DUAL))
FROM EMPLOYEE E ;

生成以下JSON:

{  
   "employeeID":"1001",
   "instID":"123456789",
   "loans":[  
      {  
         "creditLoan":[  
            {  
               "id":"123",
               "amount":"-20000"
            },
            {  
               "id":"234",
               "amount":"-30000"
            }           
         ]
      }
   ]
}

我希望避免在外部数组(贷款)中包含内部数组(creditLoan)。每个贷款对象应具有“ creditLoan”键。

此外,将多个员工JSON结构组合到单个Clob中的有效方法是什么?现在我为每位员工得到一行。

1 个答案:

答案 0 :(得分:1)

您不需要内部选择,并且还需要一层聚合:

-- CTEs for sample data
with employee (id) as (
  select 1001 from dual
),
loans (id, emp_id, amount) as (
  select 123, 1001, -20000 from dual
  union all
  select 456, 1001, -30000 from dual
)
-- actual query
SELECT JSON_OBJECT (
  'employeeID' VALUE E.ID, 
  'instID' VALUE '123456789',
  'loans' VALUE (
    JSON_ARRAYAGG (
      JSON_OBJECT (
        'creditLoan' VALUE (
          JSON_OBJECT (
            KEY 'id' VALUE L.ID,  
            KEY 'amount' VALUE L.AMOUNT
          )
        )
      )
    )
  )
)
FROM EMPLOYEE E
JOIN LOANS L ON L.EMP_ID=E.ID
GROUP BY E.ID;

得到

{  
  "employeeID":1001,
  "instID":"123456789",
  "loans":[  
    {  
      "creditLoan":{  
        "id":123,
        "amount":-20000
      }
    },
    {  
      "creditLoan":{  
        "id":456,
        "amount":-30000
      }
    }
  ]
}

如果要在一个JSON结果中包含多个员工,则需要在此之上添加另一个聚合层;像这样:

-- CTEs for sample data
with employee (id) as (
  select 1001 from dual
  union all
  select 1002 from dual
),
loans (id, emp_id, amount) as (
  select 123, 1001, -20000 from dual
  union all
  select 456, 1001, -30000 from dual
  union all
  select 789, 1002, -10000 from dual
)
-- actual query
SELECT JSON_OBJECT (
  'employees' VALUE (
    JSON_ARRAYAGG (
      JSON_OBJECT (
        'employeeID' VALUE E.ID, 
        'instID' VALUE '123456789',
        'loans' VALUE (
          JSON_ARRAYAGG (
            JSON_OBJECT (
              'creditLoan' VALUE (
                JSON_OBJECT (
                  KEY 'id' VALUE L.ID,  
                  KEY 'amount' VALUE L.AMOUNT
                )
              )
            )
          )
        )
      )
    )
  )
)
FROM EMPLOYEE E
JOIN LOANS L ON L.EMP_ID=E.ID
GROUP BY E.ID;

得到

{  
  "employees":[  
    {  
      "employeeID":1001,
      "instID":"123456789",
      "loans":[  
        {  
          "creditLoan":{  
            "id":123,
            "amount":-20000
          }
        },
        {  
          "creditLoan":{  
            "id":456,
            "amount":-30000
          }
        }
      ]
    },
    {  
      "employeeID":1002,
      "instID":"123456789",
      "loans":[  
        {  
          "creditLoan":{  
            "id":789,
            "amount":-10000
          }
        }
      ]
    }
  ]
}