sql >> Database teknologi >  >> RDS >> Oracle

Oracle-fejl producerer dublerede samlede værdier i JSON_ARRAYAGG

Det ser ud til at være en fejl. Udførelsesplanen antyder ikke nogen DISTINCT operation, der anvendes:

--------------------------------------------------------------------------- | 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 | ---------------------------------------------------------------------------

Løsning 1

Brug en dummy HAVING COUNT(*) = COUNT(*) prædikat:

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;
 

Dette giver det korrekte resultat:

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

Planen er nu:

------------------------------------------------------------------------------ | 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 | ------------------------------------------------------------------------------

Løsning 2

Brug en UNION at håndhæve særpræg:

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;
 

Planen er nu:

------------------------------------------------------------------------------ | 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 | ------------------------------------------------------------------------------

Og resultatet er også korrekt



  1. MySQL fremmednøgle for at tillade NULL?

  2. Brug NEWSEQUENTIALID() til at oprette en inkrementerende GUID i SQL Server

  3. Lagring af billeder i PostgreSQL

  4. Hvordan får jeg adgang til en tabel i et skema uden at skulle bruge skemapræfikset (Postgres + PHP)?