setup objects
create or replace type nested_item force as object (
some_id integer,
unit_cost number
);
Type created.
setup objects
create or replace type item force as object (
id integer,
sub_item nested_item
);
Type created.
setup objects
create or replace type items force as table of item;
Type created.
data generator function
create or replace function get_items(
p_how_many positiven := 10
) return items is
l_items items := items( );
begin
for i in 1 .. p_how_many loop
l_items.extend;
l_items( l_items.last ) :=
item(
id => i,
sub_item =>
nested_item(
some_id => mod( i - 1, 5 ) + 1,
unit_cost => i / 10
)
);
end loop;
return l_items;
end;
Function created.
base query and proper results
select
objs.id,
objs.sub_item.some_id,
sum( objs.sub_item.unit_cost )
from table (get_items( 10 ) ) objs
group by
objs.id,
objs.sub_item.some_id
order by
objs.id,
objs.sub_item.some_id
ID | SUB_ITEM.SOME_ID | SUM(OBJS.SUB_ITEM.UNIT_COST) | 1 | 1 | .1 | 2 | 2 | .2 | 3 | 3 | .3 | 4 | 4 | .4 | 5 | 5 | .5 | 6 | 1 | .6 | 7 | 2 | .7 | 8 | 3 | .8 | 9 | 4 | .9 | 10 | 5 | 1 |
---|
Target table for insert statement
create table target (
test_case_number integer,
item_id integer,
some_id integer,
some_value number
)
Table created.
insert from base query
insert into target (
test_case_number,
item_id,
some_id,
some_value
)
select
1 as test_case_number,
objs.id as id,
objs.sub_item.some_id as some_id,
sum( objs.sub_item.unit_cost ) as some_value
from table (get_items( 10 ) ) objs
group by
objs.id,
objs.sub_item.some_id
10 row(s) inserted.
commit
Statement processed.
check query results
select
item_id,
some_id,
some_value
from target
where test_case_number = 1
order by
item_id,
some_id
ITEM_ID | SOME_ID | SOME_VALUE | 1 | 1 | .1 | 2 | 2 | .2 | 3 | 3 | .3 | 4 | 4 | .4 | 5 | 5 | .5 | 6 | 1 | .6 | 7 | 2 | .7 | 8 | 3 | .8 | 9 | 4 | .9 | 10 | 5 | 1 |
---|
Create additional table
create table lookup (
some_id integer,
multiplier number,
constraint lookup_pk primary key ( some_id )
)
Table created.
Populate additional table
insert into lookup (
some_id, multiplier
)
select rownum, 6 - rownum
from dual connect by level <= 5
5 row(s) inserted.
commit
Statement processed.
select * from lookup
SOME_ID | MULTIPLIER | 1 | 5 | 2 | 4 | 3 | 3 | 4 | 2 | 5 | 1 |
---|
Target query
select
objs.id as id,
objs.sub_item.some_id as some_id,
sum( objs.sub_item.unit_cost * lookup.multiplier ) as some_value
from
table (get_items( 10 )) objs
join lookup
on lookup.some_id = objs.sub_item.some_id
group by objs.id, objs.sub_item.some_id
order by
objs.id,
objs.sub_item.some_id
ID | SOME_ID | SOME_VALUE | 1 | 1 | .5 | 2 | 2 | .8 | 3 | 3 | .9 | 4 | 4 | .8 | 5 | 5 | .5 | 6 | 1 | 3 | 7 | 2 | 2.8 | 8 | 3 | 2.4 | 9 | 4 | 1.8 | 10 | 5 | 1 |
---|
BUG - insert as select
insert into target (
test_case_number,
item_id,
some_id,
some_value
)
select
2 as test_case_number,
objs.id as id,
objs.sub_item.some_id as some_id,
sum( objs.sub_item.unit_cost * lookup.multiplier ) as some_value
from
table (get_items( 10 )) objs
join lookup
on lookup.some_id = objs.sub_item.some_id
group by objs.id, objs.sub_item.some_id
order by
objs.id,
objs.sub_item.some_id
10 row(s) inserted.
commit
Statement processed.
Data populated is not correct
select
item_id,
some_id,
some_value
from target
where test_case_number = 2
order by
item_id,
some_id
ITEM_ID | SOME_ID | SOME_VALUE | 1 | 5 | .5 | 2 | 5 | .8 | 3 | 5 | .9 | 4 | 5 | .8 | 5 | 5 | .5 | 6 | 5 | 3 | 7 | 5 | 2.8 | 8 | 5 | 2.4 | 9 | 5 | 1.8 | 10 | 5 | 1 |
---|
Workaround - use inline view with column aliases
insert into target (
test_case_number,
item_id,
some_id,
some_value
)
select
3 as test_case_number,
objs.id,
objs.some_id,
sum( objs.unit_cost * lookup.multiplier ) as some_value
from (
select
o.id as id,
o.sub_item.some_id as some_id,
o.sub_item.unit_cost as unit_cost
from table ( get_items( 10 ) ) o
) objs
join lookup
on lookup.some_id = objs.some_id
group by objs.id, objs.some_id
order by
objs.id,
objs.some_id
10 row(s) inserted.
commit
Statement processed.
select
item_id,
some_id,
some_value
from target
where test_case_number = 3
order by
item_id,
some_id
ITEM_ID | SOME_ID | SOME_VALUE | 1 | 1 | .5 | 2 | 2 | .8 | 3 | 3 | .9 | 4 | 4 | .8 | 5 | 5 | .5 | 6 | 1 | 3 | 7 | 2 | 2.8 | 8 | 3 | 2.4 | 9 | 4 | 1.8 | 10 | 5 | 1 |
---|
Workaround - Named sub-query with ORDER BY
insert into target (
test_case_number,
item_id,
some_id,
some_value
)
with
input_data as (
select
4 as test_case_number,
objs.id,
objs.sub_item.some_id,
sum( objs.sub_item.unit_cost * lookup.multiplier )
from
table (get_items( 10 )) objs
join lookup
on lookup.some_id = objs.sub_item.some_id
group by objs.id, objs.sub_item.some_id
order by objs.id, objs.sub_item.some_id
)
select *
from input_data
10 row(s) inserted.
commit
Statement processed.
select
item_id,
some_id,
some_value
from target
where test_case_number = 4
order by
item_id,
some_id
ITEM_ID | SOME_ID | SOME_VALUE | 1 | 1 | .5 | 2 | 2 | .8 | 3 | 3 | .9 | 4 | 4 | .8 | 5 | 5 | .5 | 6 | 1 | 3 | 7 | 2 | 2.8 | 8 | 3 | 2.4 | 9 | 4 | 1.8 | 10 | 5 | 1 |
---|
BUG - Named sub-query without ORDER BY
insert into target (
test_case_number,
item_id,
some_id,
some_value
)
with
input_data as (
select
5 as test_case_number,
objs.id,
objs.sub_item.some_id,
sum( objs.sub_item.unit_cost * lookup.multiplier )
from
table (get_items( 10 )) objs
join lookup
on lookup.some_id = objs.sub_item.some_id
group by objs.id, objs.sub_item.some_id
)
select *
from input_data
order by 1, 2
10 row(s) inserted.
commit
Statement processed.
select
item_id,
some_id,
some_value
from target
where test_case_number = 5
order by
item_id,
some_id
ITEM_ID | SOME_ID | SOME_VALUE | 1 | 5 | .5 | 2 | 5 | .8 | 3 | 5 | .9 | 4 | 5 | .8 | 5 | 5 | .5 | 6 | 5 | 3 | 7 | 5 | 2.8 | 8 | 5 | 2.4 | 9 | 5 | 1.8 | 10 | 5 | 1 |
---|
Workaround - Named sub-query without ORDER BY and with MATERIALIZE hint
insert into target (
test_case_number,
item_id,
some_id,
some_value
)
with
input_data as (
select /*+ materialize */
6 as test_case_number,
objs.id,
objs.sub_item.some_id,
sum( objs.sub_item.unit_cost * lookup.multiplier )
from
table (get_items( 10 )) objs
join lookup
on lookup.some_id = objs.sub_item.some_id
group by objs.id, objs.sub_item.some_id
)
select *
from input_data
order by 1, 2
10 row(s) inserted.
commit
Statement processed.
select
item_id,
some_id,
some_value
from target
where test_case_number = 6
order by
item_id,
some_id
ITEM_ID | SOME_ID | SOME_VALUE | 1 | 1 | .5 | 2 | 2 | .8 | 3 | 3 | .9 | 4 | 4 | .8 | 5 | 5 | .5 | 6 | 1 | 3 | 7 | 2 | 2.8 | 8 | 3 | 2.4 | 9 | 4 | 1.8 | 10 | 5 | 1 |
---|
drop function get_items
Function dropped.
drop type items
Type dropped.
drop type item
Type dropped.
drop type nested_item
Type dropped.
drop table lookup
Table dropped.
drop table target
Table dropped.