Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Błąd Oracle tworzy zduplikowane wartości zagregowane w JSON_ARRAYAGG

Wydaje się, że to błąd. Plan wykonania nie wskazuje na żaden DISTINCT wykonywana operacja:

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |       |       |     6 (100)|          |
|   1 |  SORT GROUP BY     |      |     1 |    26 |            |          |
|*  2 |   TABLE ACCESS FULL| T2   |     1 |    26 |     3   (0)| 00:00:01 |
|   3 |  SORT GROUP BY     |      |     1 |    13 |            |          |
|   4 |   TABLE ACCESS FULL| T1   |     2 |    26 |     3   (0)| 00:00:01 |
---------------------------------------------------------------------------

Obejście 1

Użyj fikcyjnego HAVING COUNT(*) = COUNT(*) orzeczenie:

select json_arrayagg(json_object(
  key 't1_id' value t1_id,
  key 't2' value (
    select json_arrayagg(json_object(
      key 't2_value' value t2_value
    ))
    from (
      select distinct t2.t2_value
      from t2
      where t2.t1_id = t1.t1_id
    ) t
    having count(*) = count(*) -- Workaround
  ) format json
))
from t1;

Daje to poprawny wynik:

[{
  "t1_id":1,
  "t2":[{ "t2_value":1 }]
}, {
  "t1_id":2,
  "t2":[{ "t2_value":2 }, { "t2_value":3 }]
}]

Plan jest teraz:

------------------------------------------------------------------------------
| Id  | Operation             | Name | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |      |       |       |     7 (100)|          |
|*  1 |  FILTER               |      |       |       |            |          |
|   2 |   SORT GROUP BY       |      |     1 |    13 |            |          |
|   3 |    VIEW               |      |     1 |    13 |     4  (25)| 00:00:01 |
|   4 |     SORT UNIQUE       |      |     1 |    26 |     4  (25)| 00:00:01 | <--
|*  5 |      TABLE ACCESS FULL| T2   |     1 |    26 |     3   (0)| 00:00:01 |
|   6 |  SORT GROUP BY        |      |     1 |    13 |            |          |
|   7 |   TABLE ACCESS FULL   | T1   |     2 |    26 |     3   (0)| 00:00:01 |
------------------------------------------------------------------------------

Obejście 2

Użyj UNION aby wymusić odrębność:

select json_arrayagg(json_object(
  key 't1_id' value t1_id,
  key 't2' value (
    select json_arrayagg(json_object(
      key 't2_value' value t2_value
    ))
    from (
      select distinct t2.t2_value
      from t2
      where t2.t1_id = t1.t1_id
      union select null from dual where 1 = 0 -- Dummy union
    ) t
  ) format json
))
from t1;

Plan jest teraz:

------------------------------------------------------------------------------
| Id  | Operation             | Name | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |      |       |       |     6 (100)|          |
|   1 |  SORT GROUP BY        |      |     1 |    13 |            |          |
|   2 |   VIEW                |      |     2 |    26 |     3   (0)| 00:00:01 |
|   3 |    SORT UNIQUE        |      |     2 |    26 |     3   (0)| 00:00:01 | <--
|   4 |     UNION-ALL         |      |       |       |            |          |
|*  5 |      TABLE ACCESS FULL| T2   |     1 |    26 |     3   (0)| 00:00:01 |
|*  6 |      FILTER           |      |       |       |            |          |
|   7 |       FAST DUAL       |      |     1 |       |     2   (0)| 00:00:01 |
|   8 |  SORT GROUP BY        |      |     1 |    13 |            |          |
|   9 |   TABLE ACCESS FULL   | T1   |     2 |    26 |     3   (0)| 00:00:01 |
------------------------------------------------------------------------------

Wynik jest również poprawny



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Zdobądź pracowników, którzy byli aktywni w określonym zakresie dat

  2. Oracle PL/SQL — zgłaszanie wyjątków zdefiniowanych przez użytkownika za pomocą niestandardowego SQLERRM

  3. Grupuj wiersze Zachowując porządek wartości

  4. Uwierzytelnianie za pomocą kluczy publicznych i cx_Oracle przy użyciu Pythona

  5. pojawia się błąd podczas tworzenia tabeli jako ORA-00904::nieprawidłowy identyfikator w bazie danych Oracle sql