Oracle 12c JSON - PullRequest
       19

Oracle 12c JSON

0 голосов
/ 30 августа 2018

У меня есть две таблицы. Сотрудник и кредиты. Последний имеет иностранную ссылку на сотрудника. Один сотрудник может иметь несколько займов. В моем упрощенном примере у нас есть только один тип кредита «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 сотрудников в один сгусток? Теперь я получаю по одной строке для каждого сотрудника.

1 Ответ

0 голосов
/ 30 августа 2018

Вам не нужны внутренние выборки, и у вас есть еще один уровень агрегации, который вы хотите:

-- 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
          }
        }
      ]
    }
  ]
}
...