Monday, January 25, 2010

12.6 Collection Functions











 < Day Day Up > 







12.6 Collection Functions





Oracle Database 10g supplies a



number of

functions that are useful when working with nested table collections.

For example, if you are interested in the number of elements in a

given collection, you can use the

CARDINALITY

function:





SELECT co.order_nbr, co.cust_nbr, co.order_dt,

  CARDINALITY(co.order_items) number_of_items


FROM cust_order_c co;



ORDER_NBR CUST_NBR ORDER_DT NUMBER_OF_ITEMS

---------- ---------- --------- ---------------

1000 9568 21-MAR-01 3







Compare this with the following query, which obtains the same results

without the benefit of the CARDINALITY function:





SELECT co.order_nbr, co.cust_nbr, co.order_dt,

COUNT(*) number_of_items

FROM cust_order_c co, TABLE(co.order_items) oi

GROUP BY co.order_nbr, co.cust_nbr, co.order_dt;



ORDER_NBR CUST_NBR ORDER_DT NUMBER_OF_ITEMS

---------- ---------- --------- ---------------

1000 9568 21-MAR-01 3







If you would like to perform set operations on

multiple collections, there are

functions that perform the equivalent of UNION, UNION ALL, MINUS, and

INTERSECT. To illustrate these functions, we will add another row to

the cust_order_c table and then perform set

operations against the two rows in the table:





INSERT INTO cust_order_c (order_nbr, cust_nbr, sales_emp_id,

order_dt, sale_price, order_items)

VALUES (1001, 9679, 275, TO_DATE('15-DEC-2003','DD-MON-YYYY'), 8645,

line_item_tbl(

line_item_obj('A675-015', 25),

line_item_obj('TX-475-A2', 7)));







Here's a look at our two sets of line items:





ORDER_ITEMS(PART_NBR, QUANTITY)

-----------------------------------------------------------------------

LINE_ITEM_TBL(LINE_ITEM_OBJ('A675-015', 25),

LINE_ITEM_OBJ('GX5-2786-A2', 1),

LINE_ITEM_OBJ('X378-9JT-2', 3))



LINE_ITEM_TBL(LINE_ITEM_OBJ('A675-015', 25),

LINE_ITEM_OBJ('TX-475-A2', 7))







As you can see, the two sets of line items share one common element

(quantity 25 of part number A675-015). The next query demonstrates

how the

MULTISET UNION DISTINCT function can

be used to build a new instance of line_item_tbl

with the distinct set of line items:





SELECT co_1.order_items 

MULTISET UNION DISTINCT

co_2.order_items distinct_items

FROM cust_order_c co_1, cust_order_c co_2

WHERE co_1.order_nbr = 1000 and co_2.order_nbr = 1001;



DISTINCT_ITEMS(PART_NBR, QUANTITY)

--------------------------------------------------------------------------

LINE_ITEM_TBL(LINE_ITEM_OBJ('A675-015', 25),

LINE_ITEM_OBJ('GX5-2786-A2', 1),

LINE_ITEM_OBJ('X378-9JT-2', 3),

LINE_ITEM_OBJ('TX-475-A2', 7))







If you want the non-distinct union of line items from the two sets,

simply replace the keyword DISTINCT with ALL:





SELECT co_1.order_items 

MULTISET UNION ALL

co_2.order_items all_items

FROM cust_order_c co_1, cust_order_c co_2

WHERE co_1.order_nbr = 1000 and co_2.order_nbr = 1001;



ALL_ITEMS(PART_NBR, QUANTITY)

--------------------------------------------------------------------------

LINE_ITEM_TBL(LINE_ITEM_OBJ('A675-015', 25),

LINE_ITEM_OBJ('GX5-2786-A2', 1),

LINE_ITEM_OBJ('X378-9JT-2', 3),

LINE_ITEM_OBJ('A675-015', 25),

LINE_ITEM_OBJ('TX-475-A2', 7))







As you would expect, the common line item now appears twice in the

all_items collection.





If you want the functionality of the MINUS set operator, you can use

the

MULTISET EXCEPT function. The keyword

EXCEPT is used rather than MINUS, to conform to the ANSI/ISO SQL

standard:





SELECT co_1.order_items 

MULTISET EXCEPT

co_2.order_items diff_items

FROM cust_order_c co_1, cust_order_c co_2

WHERE co_1.order_nbr = 1000 and co_2.order_nbr = 1001;



DIFF_ITEMS(PART_NBR, QUANTITY)

--------------------------------------------------------------------------

LINE_ITEM_TBL(LINE_ITEM_OBJ('GX5-2786-A2', 1),

LINE_ITEM_OBJ('X378-9JT-2', 3))







Finally, if you desire to generate the intersection between the two

sets, you can use the

MULTISET INTERSECT function:





SELECT co_1.order_items 

MULTISET INTERSECT

co_2.order_items common_items

FROM cust_order_c co_1, cust_order_c co_2

WHERE co_1.order_nbr = 1000 and co_2.order_nbr = 1001;



COMMON_ITEMS(PART_NBR,



QUANTITY)

--------------------------------------------------------------------------

LINE_ITEM_TBL(LINE_ITEM_OBJ('A675-015', 25))



















     < Day Day Up > 



    No comments: