Объединение json_arrayagg и json_object с json_table всегда возвращает первую строку - PullRequest
0 голосов
/ 19 февраля 2020

Следующий исходный код не возвращает ожидаемые значения, кроме случаев удаления столбцов v_f_1000 и v_f_2:

SELECT
  (SELECT v_f
  FROM json_table(R_P.json_data, '$[*]' columns (r_p_i NUMBER path '$.r_p_i', v_f path '$.v_f'))
  WHERE r_p_i = 1000
  ) AS "v_f_1000",
  (SELECT v_f
  FROM json_table(R_P.json_data, '$[*]' columns (r_p_i NUMBER path '$.r_p_i', v_f path '$.v_f'))
  WHERE r_p_i = 2
  ) AS "v_f_2",
  R_P.json_data,
  R_P.r_c,
  R_P.r_r
FROM
  (SELECT json_arrayagg(json_object(KEY 'r_p_i' value r_p_i, KEY 'v_f' value v_f, KEY 'u_i' value u_i ABSENT ON NULL)
  ORDER BY NULL) json_data,
    r_c,
    r_r
  FROM
    (SELECT '26658' AS r_c,
      '00'          AS r_r,
      1000          AS r_p_i,
      8.5           AS v_f,
      'MM'          AS u_i
    FROM dual
    UNION ALL
    SELECT '26917' AS r_c,
      '00'         AS r_r,
      2            AS r_p_i,
      10           AS v_f,
      'R71'        AS u_i
    FROM dual
    )
  GROUP BY r_c,
    r_r
  ) R_P;

Фактический результат:

8.5   null  [{"r_p_i":1000,"v_f":8.5,"u_i":"MM"}]   26658   00
8.5   null  [{"r_p_i":1000,"v_f":8.5,"u_i":"MM"}]   26917   00

Ожидается результат:

8.5   null  [{"r_p_i":1000,"v_f":8.5,"u_i":"MM"}]   26658   00 
null  10    [{"r_p_i":2,"v_f":10,"u_i":"R71"}]      26917   00

Я использую Oracle 12.2.0.1.0 и Oracle 19.0.0.0.0. Я попробовал несколько подсказок оптимизатора безуспешно, NO_QUERY_TRANSFORMATION выдает ошибку ORA-600. Я думаю, что это ошибка, R_P.json_data не должно отличаться, когда я добавляю столбцы v_f_1000 и v_f_2 в предложение select.

1 Ответ

0 голосов
/ 19 февраля 2020

Я все еще думаю, что моя первая реализация выше должна работать как положено (об этом будет сообщено как ошибка), но замена json_arrayagg на json_objectagg и json_table на json_value заставляет его работать:

SELECT JSON_VALUE(R_P.json_data, '$."1000".v_f') AS "v_f_1000",
  JSON_VALUE(R_P.json_data, '$."2".v_f')         AS "v_f_2",
  R_P.json_data,
  R_P.r_c,
  R_P.r_r
FROM
  (SELECT json_objectagg(KEY TO_CHAR(r_p_i) value json_object(KEY 'v_f' value v_f, KEY 'u_i' value u_i ABSENT ON NULL)) AS json_data,
    r_c,
    r_r
  FROM
    (SELECT '26658' AS r_c,
      '00'          AS r_r,
      1000          AS r_p_i,
      8.5           AS v_f,
      'MM'          AS u_i
    FROM dual
    UNION ALL
    SELECT '26917' AS r_c,
      '00'         AS r_r,
      2            AS r_p_i,
      10           AS v_f,
      'R71'        AS u_i
    FROM dual
    )
  GROUP BY r_c,
    r_r
  ) R_P;

Важно обновление : вызова to_char() для данных JSON при передаче их на json_table кажется достаточным для решения моей проблемы:

SELECT
  (SELECT v_f
  FROM json_table(to_char(R_P.json_data), '$[*]' columns (r_p_i NUMBER path '$.r_p_i', v_f path '$.v_f'))
  WHERE r_p_i = 1000
  ) AS "v_f_1000",
  (SELECT v_f
  FROM json_table(to_char(R_P.json_data), '$[*]' columns (r_p_i NUMBER path '$.r_p_i', v_f path '$.v_f'))
  WHERE r_p_i = 2
  ) AS "v_f_2",
  R_P.json_data,
  R_P.r_c,
  R_P.r_r
FROM
  (SELECT json_arrayagg(json_object(KEY 'r_p_i' value r_p_i, KEY 'v_f' value v_f, KEY 'u_i' value u_i ABSENT ON NULL)
  ORDER BY NULL) json_data,
    r_c,
    r_r
  FROM
    (SELECT '26658' AS r_c,
      '00'          AS r_r,
      1000          AS r_p_i,
      8.5           AS v_f,
      'MM'          AS u_i
    FROM dual
    UNION ALL
    SELECT '26917' AS r_c,
      '00'         AS r_r,
      2            AS r_p_i,
      10           AS v_f,
      'R71'        AS u_i
    FROM dual
    )
  GROUP BY r_c,
    r_r
  ) R_P;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...