Изглежда, че е грешка. Планът за изпълнение не загатва за DISTINCT
приложена операция:
---------------------------------------------------------------------------
| 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 |
---------------------------------------------------------------------------
Заобиколно решение 1
Използвайте фиктивен HAVING COUNT(*) = COUNT(*)
предикат:
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;
Това дава правилния резултат:
[{
"t1_id":1,
"t2":[{ "t2_value":1 }]
}, {
"t1_id":2,
"t2":[{ "t2_value":2 }, { "t2_value":3 }]
}]
Планът сега е:
------------------------------------------------------------------------------
| 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 |
------------------------------------------------------------------------------
Заобиколно решение 2
Използвайте UNION
за налагане на различимост:
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;
Планът сега е:
------------------------------------------------------------------------------
| 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 |
------------------------------------------------------------------------------
И резултатът също е правилен