Warning: Declaration of Suffusion_MM_Walker::start_el(&$output, $item, $depth, $args) should be compatible with Walker_Nav_Menu::start_el(&$output, $item, $depth = 0, $args = Array, $id = 0) in /DISK2/WWW/plsql.cz/www/wp-content/themes/suffusion/library/suffusion-walkers.php on line 39
Feb 162013
 

Minutý rychlotip byl o funkci DBMS_FREQUENT_ITEMSET.FI_HORIZONTAL, která vytvoří z hodnot sloupců všechny možné množiny a spočítá jejich výskyt zkrt všechny řádky – funkce zajimavá, o praktickém použití v denním programování to však není. Balík DBMS_FREQUENT_ITEMSET obsahuje ještě jednu pipelined funkci - FI_TRANSACTIONAL.  Signatura funkce je stejná jako u FI_HORIZONTAL:



DBMS_FREQUENT_ITEMSET.FI_TRANSACTIONAL (
 tranx_cursor IN SYSREFCURSOR,
 support_threshold IN NUMBER,
 itemset_length_min IN NUMBER,
 itemset_length_max IN NUMBER,
 including_items IN SYS_REFCURSOR DEFAULT NULL,
 excluding_items IN SYS_REFCURSOR DEFAULT NULL)
RETURN TABLE OF ROW (
 itemset [Nested Table of Item Type DERIVED FROM tranx_cursor],
 support NUMBER,
 length NUMBER,
total_tranx NUMBER);

Zatímco první funkce FI_HORIZONTAL tvoří množiny všech množin z hodnot ve sloupích a výskyt množin pak počítá skrz řádky, FI_TRANSACTIONAL vypadá, že by se mohla chovat opačně, respektive být otočená o 90% – tvořit množiny všech množin zkz sloupce a počítat je zkz řádky – není tomu tak! Narozdíl od FI_HORIZONTAL kam může vstupovat select, který má v projection libovolný počet sloupců (ale stejného typu) do FI_TRANSACTIONAL může vstupovat do parametru tranx_cursor pouze select jež má v projection pouze dva sloupce  – (number,<nějaký_jednoduchý_typ>), kde první sloupce typu number určuje skupinu zkz kterou se mají generovat všechny množiny a ve druhém jsou hodnoty.

Takže go, hébičky go, pojďme si to zkusit:
Tabulka je velice podobná jako zde, s tím rozdílem, že jsem se rozhodl přidat ještě jeden sloupec – name_6:

create table tbl_drks
(name_1 varchar2(20),
name_2 varchar2(20),
name_3 varchar2(20),
name_4 varchar2(20),
name_5 varchar2(20),
name_6 varchar2(20));

A nyní insert nějakých dat (stejné jako minule + sloupec name_6):

insert into tbl_drks values('RedBull','BigShock','RockStar',null,'Monster','A');
insert into tbl_drks values('BigShock','RedBull',null, null,'Monster','B');
insert into tbl_drks values('BigShock','RedBull','BigShock',null,'RedBull','C');
insert into tbl_drks values('BigShock','RedBull',null, null,'Monster','D');
insert into tbl_drks values('Monster','RedBull',null, null,'Monster','E');
insert into tbl_drks values('Monster','RedBull','RockStar','BigShock','Monster','F');
insert into tbl_drks values('RockStar','RedBull','BigShock','BigShock','Monster','G');
insert into tbl_drks values('RockStar','RedBull','RockStar','RockStar','Monster','H');
commit;

Což v tabulce pak vypadá nějak takto:

Vstupní data pro DBMS_FREQUENT_ITEMSET.fi_transactional

Funkce DBMS_FREQUENT_ITEMSET.fi_transactional povoluje tedy jako vstup select s projection se sloupcem typu number a druhým sloupcem s hodnotou, tedy nebude stačit jen select * from tbl_drinks, ale je třeba to rozdělit po skupinách – každý sloupec jako jiná skupina, nejjednodušeji tedy pomocí union all:

SELECT CAST(itemset as typ_name)itemset, support, length, total_tranx
FROM table(DBMS_FREQUENT_ITEMSET.FI_TRANSACTIONAL(
 CURSOR(SELECT 1 as skupina_1,name_1 FROM TBL_DRKS
  union all
  SELECT 2 as skupina_2,name_2 FROM TBL_DRKS
   union all
  SELECT 3 as skupina_3,name_3 FROM TBL_DRKS
   union all
  SELECT 4 as skupina_4,name_4 FROM TBL_DRKS
   union all
  SELECT 5 as skupina_5,name_5 FROM TBL_DRKS),
0,1,8));

Výsledky dbms_frequent_itemset.fi_transactional

Příklad intepratace výsledku - třeba jednoprvková množina (Monster), která se vyskytuje ve dvou sloupcích( name_1 a name_5) a proto má support 2, jedná se o jednoprvkovou množinu, proto je length 1 a konečně počet skupin (name_1..name_5) bylo 5 tedy total_tranx 5. Parametr 0 řiká, že neomezujeme výskyt na žádné minumum, parametr 1 říká, že minimální množina je jednoprvková a parametr 8, že maximální dovolená množina je 8 prvková.

Poslední sloupec – name_6 jsem jako další skupinu dal až v následujícím selectu:

Ukázka výsledku DBBMS_FRQUENT_ITEMSET.fi_transactional - count

Ukázka výsledku DBBMS_FRQUENT_ITEMSET.fi_transactional - count

Proč pouze count? Neb mimo 15 množin, které vznikly ze sloupců name_1..name_5 jsou tu ještě monžiny, které vzniknou z 8 řádků slupce name_6. A vzhledem k hodnotám A,B,C,D,E,F,G,H vznikne vcelku dost rozdílných množin: (A),(A,B) .. Konkrétně by to měly být všechny jednoprovkové, dvojprvkové, tříprvkové.. něco takového:

Počet všech možných množin z prvků A,B,C,D,E,F,G,H

Počet všech možných množin z prvků A,B,C,D,E,F,G,H

Na spočítání takovéhleho výrazu je třeba umět spočítat faktorial:

create or replace function factorial(a number) return number
 is
  ret number:=1;
 begin
 if a=0 then return 1; end if;
 for i in 1..a loop ret:=ret*i; end loop;
 return ret;
 end;

Ok, není to zrovna hezky napsaná funkce, nicméně umožní nám to spočítat výsledek:

select sum(factorial(8)/(factorial(rownum)*factorial(8-rownum))) from dual connect by level<=8;
255

Což v kombinaci s počtem množin vzniklých z name_1..name_2 – 15 dává dohromady 15+255=270. Tedy funguje dle očekávání trhu ;)
To by bylo asi vše k DMBS_FREQUENT_ITEMSET.fi_transactional – všechno ostatní funguje jako u fi_horizontal – opakující prvky se nepočítají (tzn, každá z 255 množin ze sloupce name_6 bude mít support=1) a je možné postrčit jako nepovinný parametr hodnoty, které být musí v množinách a naopak se zbavit množiny které mají nějaký námi určený prvek. A podobně jako předchozí rychlotip, exekuční plán:

Exekuční plán pro dbms_frequent_itemset.fi_transactional

Exekuční plán pro dbms_frequent_itemset.fi_transactional

 Posted by at 12:03

 Leave a Reply

(required)

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>