SlideShare una empresa de Scribd logo
1 de 51
BASEL BERN BRUGG DÜSSELDORF FRANKFURT A.M. FREIBURG I.BR. GENF
HAMBURG KOPENHAGEN LAUSANNE MÜNCHEN STUTTGART WIEN ZÜRICH
Data Twisting
OUGN Spring Seminar 10-12 March 2016
Kim Berg Hansen
Senior Consultant
• Danish geek
• SQL & PL/SQL developer since 2000
• Developer at Trivadis AG since 2016
http://www.trivadis.dk
• Oracle Certified Expert in SQL
• Oracle ACE
• Blogger at http://www.kibeha.dk
• SQL quizmaster at
http://plsqlchallenge.oracle.com
• Likes to cook
• Reads sci-fi
• Chairman of local chapter of
Danish Beer Enthusiasts
About me
Data Twisting2 3/30/2016
About Trivadis
Data Twisting3 3/30/2016
Trivadis is a market leader in IT consulting, system integration, solution engineering
and the provision of IT services focusing on and
technologies in Switzerland, Germany, Austria and Denmark.
We offer our services in the following strategic business fields:
Trivadis Services takes over the interacting operation of your IT systems.
O P E R A T I O N
COPENHAGEN
MUNICH
LAUSANNE
BERN
ZURICH
BRUGG
GENEVA
HAMBURG
DÜSSELDORF
FRANKFURT
STUTTGART
FREIBURG
BASEL
VIENNA
With over 600 specialists and IT experts in your region
Data Twisting4 3/30/2016
14 Trivadis branches and more than
600 employees
260 Service Level Agreements
Over 4,000 training participants
Research and development budget:
EUR 5.0 million
Financially self-supporting and
sustainably profitable
Experience from more than 1,900
projects per year at over 800
customers
Agenda for Data Twisting
Data Twisting5 3/30/2016
1. Why do we need to Twist, Shake, Rattle ‘n‘ Roll
2. Twist
UNPIVOT with single or multi-column dimensions
Unpivoting with row generators
3. Shake
PIVOT with single or multi-column dimensions, with or without grouping
Pivoting with GROUP BY and CASE
4. Rattle
Turning delimited data into columns and rows
ODCI dynamic table function parser
5. Roll
LISTAGG to turn rows into delimited data
Alternative methods for string aggregation
6. Coda
Data Twisting6 3/30/2016
Twist, Shake, Rattle ’n’ Roll
EMEA AMER ASOC
Beer
WineWine
Twist Columns to Rows
Data Twisting7 3/30/2016
Category Region Sales
Beer
Wine
200000
10000
150000
25000
225000
17500
EMEA AMER ASOC
Beer
EMEA
AMER
ASOC
Beer
Wine
Wine
Shake Rows to Columns
Data Twisting8 3/30/2016
Category Region Sales
Beer
Wine
200000
10000
150000
25000
225000
EMEA
AMER
ASOCBeer
17500
Beer
Wine
Rattle Delimited Data to Columns
Data Twisting9 3/30/2016
CategoryEMEAAMER
200000
10000
150000
25000
225000
17500
ASOCCategory;EMEA;AMER;ASOC
Beer;200000;150000;225000
Wine;10000;25000;17500
Rattle Delimited Data to Rows
Data Twisting10 3/30/2016
Category
BeerBeer
Type
PilsnerBeer
WineWine
AleStout
RedChampagne
TypeList
Pilsner;Ale;Stout
Red;Champagne
TypeList
Pilsner;Ale;Stout
Red;Champagne
Roll Rows to Delimited Data
Data Twisting11 3/30/2016
Category
Beer
Beer
Beer
Wine
Wine
Type
Pilsner
Ale
Stout
Red
Champagne
Data Twisting12 3/30/2016
Twist
Single dimension and measure
Data Twisting13 3/30/2016
create table sales1 (
category varchar2(10)
, emea number
, amer number
, asoc number
);
insert into sales1 values ('Beer', 200000, 150000, 225000);
insert into sales1 values ('Wine', 10000, 25000, 17500);
Table of beverage sales with columns per region
Single dimension and measure
Data Twisting14 3/30/2016
select category, region, sales
from sales1
unpivot (
sales
for region in (
emea as 'EMEA'
, amer as 'AMER'
, asoc as 'ASOC'
)
)
order by category, region;
UNPIVOT create dimension REGION and measure SALES
CATEGORY REGI SALES
---------- ---- ----------
Beer AMER 150000
Beer ASOC 225000
Beer EMEA 200000
Wine AMER 25000
Wine ASOC 17500
Wine EMEA 10000
Single dimension and measure
Data Twisting15 3/30/2016
select category
, case n# when 1 then 'EMEA'
when 2 then 'AMER'
when 3 then 'ASOC'
end region
, case n# when 1 then emea
when 2 then amer
when 3 then asoc
end sales
from sales1
cross join (
select level n# from dual
connect by level <= 3
)
order by category, region;
Generate 3 rows - Cartesian join – CASE logic for dimension and measure
CATEGORY REGI SALES
---------- ---- ----------
Beer AMER 150000
Beer ASOC 225000
Beer EMEA 200000
Wine AMER 25000
Wine ASOC 17500
Wine EMEA 10000
Single dimension and measure
Data Twisting16 3/30/2016
with r (region) as (
select 'EMEA' from dual union all
select 'AMER' from dual union all
select 'ASOC' from dual
)
select category, region
, case region
when 'EMEA' then emea
when 'AMER' then amer
when 'ASOC' then asoc
end sales
from sales1
cross join r
order by category, region;
Generate 3 rows with dimension - Cartesian join – CASE logic for measure
CATEGORY REGI SALES
---------- ---- ----------
Beer AMER 150000
Beer ASOC 225000
Beer EMEA 200000
Wine AMER 25000
Wine ASOC 17500
Wine EMEA 10000
Multiple dimensions and measures
Data Twisting17 3/30/2016
create table sales2 (
category varchar2(10)
, dk_b2b_qty number , dk_b2b_amount number
, dk_b2c_qty number , dk_b2c_amount number
, uk_b2b_qty number , uk_b2b_amount number
, uk_b2c_qty number , uk_b2c_amount number
);
insert into sales2 values ('Beer', 500, 5000, 250, 2500, 100, 1000, 200, 2000);
insert into sales2 values ('Wine', 150, 3000, 200, 4000, 400, 8000, 300, 6000);
Table of beverage sales with qty and amount columns per country and channel
Multiple dimensions and measures
Data Twisting18 3/30/2016
select category, country, channel, qty, amount
from sales2
unpivot (
( qty, amount )
for ( country, channel )
in (
(dk_b2b_qty, dk_b2b_amount) as ('DK', 'B2B')
, (dk_b2c_qty, dk_b2c_amount) as ('DK', 'B2C')
, (uk_b2b_qty, uk_b2b_amount) as ('UK', 'B2B')
, (uk_b2c_qty, uk_b2c_amount) as ('UK', 'B2C')
)
)
order by category, country, channel;
UNPIVOT create dimensions COUNTRY, CHANNEL and measures QTY, AMOUNT
CATEGORY CO CHA QTY AMOUNT
---------- -- --- ----- -------
Beer DK B2B 500 5000
Beer DK B2C 250 2500
Beer UK B2B 100 1000
Beer UK B2C 200 2000
Wine DK B2B 150 3000
Wine DK B2C 200 4000
Wine UK B2B 400 8000
Wine UK B2C 300 6000
Single dimension and multiple measures
Data Twisting19 3/30/2016
select category, country_and_channel, qty, amount
from sales2
unpivot (
( qty, amount )
for ( country_and_channel )
in (
(dk_b2b_qty, dk_b2b_amount) as ('DK_B2B')
, (dk_b2c_qty, dk_b2c_amount) as ('DK_B2C')
, (uk_b2b_qty, uk_b2b_amount) as ('UK_B2B')
, (uk_b2c_qty, uk_b2c_amount) as ('UK_B2C')
)
)
order by category, country_and_channel;
UNPIVOT create dimension COUNTRY_AND_CHANNEL - measures QTY, AMOUNT
CATEGORY COUNTR QTY AMOUNT
---------- ------ ----- -------
Beer DK_B2B 500 5000
Beer DK_B2C 250 2500
Beer UK_B2B 100 1000
Beer UK_B2C 200 2000
Wine DK_B2B 150 3000
Wine DK_B2C 200 4000
Wine UK_B2B 400 8000
Wine UK_B2C 300 6000
Multiple dimensions and single measure
Data Twisting20 3/30/2016
select category, country, channel, amount
from sales2
unpivot (
( amount )
for ( country, channel )
in (
(dk_b2b_amount) as ('DK', 'B2B')
, (dk_b2c_amount) as ('DK', 'B2C')
, (uk_b2b_amount) as ('UK', 'B2B')
, (uk_b2c_amount) as ('UK', 'B2C')
)
)
order by category, country, channel;
UNPIVOT create dimensions COUNTRY, CHANNEL - measure AMOUNT
CATEGORY CO CHA AMOUNT
---------- -- --- ----------
Beer DK B2B 5000
Beer DK B2C 2500
Beer UK B2B 1000
Beer UK B2C 2000
Wine DK B2B 3000
Wine DK B2C 4000
Wine UK B2B 8000
Wine UK B2C 6000
Data Twisting21 3/30/2016
Shake
Single dimension and measure
Data Twisting22 3/30/2016
create table sales3 (
category varchar2(10)
, region varchar2(10)
, sales number
);
insert into sales3 values ('Beer', 'EMEA', 200000);
insert into sales3 values ('Beer', 'AMER', 150000);
insert into sales3 values ('Beer', 'ASOC', 225000);
insert into sales3 values ('Wine', 'EMEA', 10000);
insert into sales3 values ('Wine', 'AMER', 25000);
insert into sales3 values ('Wine', 'ASOC', 17500);
Table of beverage sales per region
Single dimension and measure
Data Twisting23 3/30/2016
select category, emea, amer, asoc
from sales3
pivot (
sum(sales)
for region in (
'EMEA' as emea
, 'AMER' as amer
, 'ASOC' as asoc
)
)
order by category;
PIVOT create 3 columns for 3 dimension values and 1 measure
CATEGORY EMEA AMER ASOC
---------- ------- ------- -------
Beer 200000 150000 225000
Wine 10000 25000 17500
Single dimension and measure
Data Twisting24 3/30/2016
select category
, sum(case region
when 'EMEA' then sales
end) as emea
, sum(case region
when 'AMER' then sales
end) as amer
, sum(case region
when 'ASOC' then sales
end) as asoc
from sales3
group by category
order by category;
GROUP BY using CASE statement within SUM for each of the 3 dimension values
CATEGORY EMEA AMER ASOC
---------- ------- ------- -------
Beer 200000 150000 225000
Wine 10000 25000 17500
Single dimension and measure
Data Twisting25 3/30/2016
insert into sales3 values
('Beer', 'AMER', 25000);
commit;
select category, emea, amer, asoc
from sales3
pivot (
sum(sales)
for region in (
'EMEA' as emea
, 'AMER' as amer
, 'ASOC' as asoc
)
)
order by category;
Aggregations used for non-unique dimensions
CATEGORY EMEA AMER ASOC
---------- ------- ------- -------
Beer 200000 175000 225000
Wine 10000 25000 17500
Single dimension and multiple measures
Data Twisting26 3/30/2016
select *
from sales3
pivot (
sum(sales)
, count(*)
for region in (
'EMEA' as emea
, 'AMER' as amer
, 'ASOC' as asoc
)
)
order by category;
Columns are named <dim>_<measure> , so problem if no measure aliases
ERROR at line 1:
ORA-00918: column ambiguously defined
Single dimension and multiple measures
Data Twisting27 3/30/2016
CATEGORY EMEA_SALE EMEA_CNT AMER_SALE AMER_CNT ASOC_SALE ASOC_CNT
-------- --------- -------- --------- -------- --------- --------
Beer 200000 1 175000 2 225000 1
Wine 10000 1 25000 1 17500 1
select category, emea_sale, emea_cnt, amer_sale, amer_cnt, asoc_sale, asoc_cnt
from sales3
pivot (
sum(sales) as sale, count(*) as cnt
for region in (
'EMEA' as emea, 'AMER' as amer, 'ASOC' as asoc
)
)
order by category;
With measure aliases we get 3x2 columns named <dim>_<measure> combinations
Multiple dimensions and measures
Data Twisting28 3/30/2016
create table sales4 (
category varchar2(10)
, country varchar2(10)
, channel varchar2(10)
, qty number
, amount number
);
insert into sales4 values('Beer', 'DK', 'B2B', 500, 5000);
insert into sales4 values('Beer', 'DK', 'B2C', 250, 2500);
insert into sales4 values('Beer', 'UK', 'B2B', 100, 1000);
insert into sales4 values('Beer', 'UK', 'B2C', 200, 2000);
insert into sales4 values('Wine', 'DK', 'B2B', 150, 3000);
insert into sales4 values('Wine', 'DK', 'B2C', 200, 4000);
insert into sales4 values('Wine', 'UK', 'B2B', 400, 8000);
insert into sales4 values('Wine', 'UK', 'B2C', 300, 6000);
Table of beverage sales measured in qty and amount per country and channel
Multiple dimensions and measures
Data Twisting29 3/30/2016
CATEGORY DK_B2B_QTY DK_B2B_AMOUNT DK_B2C_QTY DK_B2C_AMOUNT UK_B2B_QTY UK_B2B_AMOUNT UK_B2C_QTY UK_B2C_AMOUNT
---------- ---------- ------------- ---------- ------------- ---------- ------------- ---------- -------------
Beer 500 5000 250 2500 100 1000 200 2000
Wine 150 3000 200 4000 400 8000 300 6000
select category, dk_b2b_qty, dk_b2b_amount, dk_b2c_qty, dk_b2c_amount
, uk_b2b_qty, uk_b2b_amount, uk_b2c_qty, uk_b2c_amount
from sales4 pivot (
sum(qty) as qty, sum(amount) as amount
for ( country, channel ) in ( ('DK', 'B2B') as dk_b2b
, ('DK', 'B2C') as dk_b2c
, ('UK', 'B2B') as uk_b2b
, ('UK', 'B2C') as uk_b2c )
) order by category;
With dimension and measure aliases we get (2x2)x2 columns
Data Twisting30 3/30/2016
Rattle
Delimited data to columns
Data Twisting31 3/30/2016
create table sales5 (
txt varchar2(100)
);
insert into sales5 values ('Beer;200000;150000;225000');
insert into sales5 values ('Wine;10000;25000;17500');
Table of beverage sales as semi-colon separated text
Delimited data to columns
Data Twisting32 3/30/2016
CATEGORY EMEA AMER ASOC
-------- ------ ------ ------
Beer 200000 150000 225000
Wine 10000 25000 17500
select substr(txt, 1, instr(txt,';') - 1) category
, substr(
txt, instr(txt,';') + 1, instr(txt,';',1,2) - instr(txt,';') -1
) emea
, substr(
txt, instr(txt,';',1,2) + 1, instr(txt,';',1,3) - instr(txt,';',1,2) - 1
) amer
, substr(txt, instr(txt,';',1,3) + 1) asoc
from sales5
order by category;
Using SUBSTR and INSTR
Delimited data to columns
Data Twisting33 3/30/2016
CATEGORY EMEA AMER ASOC
-------- ------ ------ ------
Beer 200000 150000 225000
Wine 10000 25000 17500
select regexp_substr(txt, '[^;]+', 1, 1) category
, regexp_substr(txt, '[^;]+', 1, 2) emea
, regexp_substr(txt, '[^;]+', 1, 3) amer
, regexp_substr(txt, '[^;]+', 1, 4) asoc
from sales5
order by category;
Using REGEXP_SUBSTR
Delimited data to rows
Data Twisting34 3/30/2016
create table beverages1 (
category varchar2(10)
, typelist varchar2(100)
);
insert into beverages1 values ('Beer', 'Pilsner;Ale;Stout');
insert into beverages1 values ('Wine', 'Red;Champagne');
Table of beverage types as semi-colon separated text
Delimited data to rows
Data Twisting35 3/30/2016
create type beverage_collection_type as table of varchar2(10);
/
create or replace function beverage_typelist_to_coll ( typelist in beverages1.typelist%type )
return beverage_collection_type pipelined
is
list_len pls_integer;
from_pos pls_integer;
to_pos pls_integer;
begin
list_len := length(typelist);
from_pos := 1;
loop
to_pos := nvl(nullif(instr(typelist, ';', from_pos), 0), list_len+1);
pipe row (substr(typelist, from_pos, to_pos-from_pos));
exit when to_pos > list_len;
from_pos := to_pos + 1;
end loop;
end beverage_typelist_to_coll;
/
Collection type and pipelined function to parse string and pipe out collection
Delimited data to rows
Data Twisting36 3/30/2016
select category
, column_value as beverage_type
from beverages1
, table(beverage_typelist_to_coll(typelist))
order by category, beverage_type;
Use pipelined table function within TABLE
CATEGORY BEVERAGE_T
-------- ----------
Beer Ale
Beer Pilsner
Beer Stout
Wine Champagne
Wine Red
Delimited data to rows
Data Twisting37 3/30/2016
select category
, regexp_substr(typelist, '[^;]+', 1, sub#) beverage_type
from beverages1
cross join lateral (
select level sub#
from dual
connect by level <= regexp_count(typelist, ';') + 1
)
order by category, beverage_type;
Generate count of delimiters + 1 rows per category (note: LATERAL requires 12c)
CATEGORY BEVERAGE_T
-------- ----------
Beer Ale
Beer Pilsner
Beer Stout
Wine Champagne
Wine Red
Delimited/structured data to rows and columns
Data Twisting38 3/30/2016
create table beverages2 (
category varchar2(10)
, typelist varchar2(100)
);
insert into beverages2 values ('Beer', 'Pilsner|Light;Ale|Medium;Stout|Dark');
insert into beverages2 values ('Wine', 'Red|Red;Champagne|Clear');
Table of beverage types and colors as semi-colon and pipe separated text
Delimited/structured data to rows and columns
Data Twisting39 3/30/2016
create or replace type delimited_col_row as object (
{globals}
, static function parser( {params} ) return anydataset pipelined using delimited_col_row
, static function odcitabledescribe( {params} ) return number
, static function odcitableprepare( {params} ) return number
, static function odcitablestart( {params} ) return number
, member function odcitablefetch( {params} ) return number
, member function odcitableclose( {params} ) return number
)
/
create or replace type body delimited_col_row as
{implementation}
end;
/
Object type implementing ODCI functions (complete code in script: http://bit.ly/kibeha_datatwist_sql)
Delimited/structured data to rows and columns
Data Twisting40 3/30/2016
select category, beverage_type, color
from beverages2
, table(
delimited_col_row.parser(
typelist
, 'BEVERAGE_TYPE|VARCHAR2(10);COLOR|VARCHAR2(10)'
, '|'
, ';'
)
) type_and_color
order by category, beverage_type;
Use ODCI parser function within TABLE – Column definition string must be a literal
CATEGORY BEVERAGE_T COLOR
-------- ---------- ----------
Beer Ale Medium
Beer Pilsner Light
Beer Stout Dark
Wine Champagne Clear
Wine Red Red
Data Twisting41 3/30/2016
Roll
Rows to delimited data
Data Twisting42 3/30/2016
create table beverages3 (
category varchar2(10)
, beverage_type varchar2(10)
);
insert into beverages3 values ('Beer', 'Pilsner');
insert into beverages3 values ('Beer', 'Ale');
insert into beverages3 values ('Beer', 'Stout');
insert into beverages3 values ('Wine', 'Red');
insert into beverages3 values ('Wine', 'Champagne');
Table of beverage types per category
Rows to delimited data
Data Twisting43 3/30/2016
select category
, listagg(beverage_type, ';')
within group (
order by beverage_type
) typelist
from beverages3
group by category
order by category;
LISTAGG built-in aggregate function (11.2)
CATEGORY TYPELIST
-------- --------------------
Beer Ale;Pilsner;Stout
Wine Champagne;Red
Rows to delimited data
Data Twisting44 3/30/2016
create type beverage_collection_type as table of varchar2(10);
/
create or replace function beverage_typecoll_to_string ( typecoll in beverage_collection_type )
return varchar2
is
type_string varchar2(4000);
begin
for idx in typecoll.first .. typecoll.last loop
if idx = typecoll.first then
type_string := typecoll(idx);
else
type_string := type_string || ';' || typecoll(idx);
end if;
end loop;
return type_string;
end beverage_typecoll_to_string;
/
Create collection type and a function to turn collection into delimited string
Rows to delimited data
Data Twisting45 3/30/2016
select category
, beverage_typecoll_to_string(
cast(
collect(
beverage_type
order by beverage_type
)
as beverage_collection_type
)
) typelist
from beverages3
group by category
order by category;
Use COLLECT to aggregate into collection, then call function to create string
CATEGORY TYPELIST
-------- --------------------
Beer Ale;Pilsner;Stout
Wine Champagne;Red
Rows to delimited data
Data Twisting46 3/30/2016
create or replace type string_agg_type as object(
total varchar2(4000),
static function ODCIAggregateInitialize( {params} ) return number,
member function ODCIAggregateIterate( {params} ) return number,
member function ODCIAggregateTerminate( {params} ) return number,
member function ODCIAggregateMerge( {params} ) return number );
/
create or replace type body string_agg_type
{implementation}
end;
/
create or replace function stragg( input varchar2 ) return varchar2
parallel_enable aggregate using string_agg_type;
/
Tom Kyte STRAGG function using ODCI implementation of user aggregate function
https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:2196162600402
Rows to delimited data
Data Twisting47 3/30/2016
select category
, stragg(beverage_type) typelist
from beverages3
group by category
order by category;
Use STRAGG like any aggregate – Note unlike LISTAGG this can not ORDER BY
CATEGORY TYPELIST
-------- --------------------
Beer Pilsner;Stout;Ale
Wine Red;Champagne
Data Twisting48 3/30/2016
Coda
We Can Boogie
Data Twisting49 3/30/2016
Twist Columns to Rows
– UNPIVOT or dummy row generators
Shake Rows to Columns
– PIVOT or GROUP BY with CASE
Rattle Delimited Data to Columns or Rows
– Parse delimited data
Roll Rows to Delimited Data
– LISTAGG or other string aggregation techniques
Boogie! 
Data Twisting50 3/30/2016
Links
This presentation PowerPoint http://bit.ly/kibeha_datatwist_pptx
Script with all examples from this presentation http://bit.ly/kibeha_datatwist_sql
Questions & Answers
Kim Berg Hansen
Senior Consultant
kim.berghansen@trivadis.com
3/30/2016 Data Twisting51
http://bit.ly/kibeha_datatwist_pptx
http://bit.ly/kibeha_datatwist_sql

Más contenido relacionado

Similar a Data twisting

Shuttling Proposal PowerPoint Presentation Slides
Shuttling Proposal PowerPoint Presentation SlidesShuttling Proposal PowerPoint Presentation Slides
Shuttling Proposal PowerPoint Presentation Slides
SlideTeam
 
Hoover's work gallery jan mar 2011
Hoover's work gallery jan mar 2011Hoover's work gallery jan mar 2011
Hoover's work gallery jan mar 2011
Ankit Gandhi
 
Portfolio_OneSheet_RP
Portfolio_OneSheet_RPPortfolio_OneSheet_RP
Portfolio_OneSheet_RP
Robert Pagan
 
The select statement
The select statementThe select statement
The select statement
punu_82
 
упаковка готовая к выкладке
упаковка готовая к выкладкеупаковка готовая к выкладке
упаковка готовая к выкладке
ECR Community
 
Fvdi abrites commander
Fvdi abrites commanderFvdi abrites commander
Fvdi abrites commander
EchoCullen
 
Fvdi abrites commander
Fvdi abrites commanderFvdi abrites commander
Fvdi abrites commander
Landy Lan
 
Cps 2011 nov overview
Cps 2011 nov overviewCps 2011 nov overview
Cps 2011 nov overview
tan805
 

Similar a Data twisting (18)

Make your data dance: PIVOT, UNPIVOT & GROUP BY extensions
Make your data dance: PIVOT, UNPIVOT & GROUP BY extensionsMake your data dance: PIVOT, UNPIVOT & GROUP BY extensions
Make your data dance: PIVOT, UNPIVOT & GROUP BY extensions
 
Shuttling Proposal PowerPoint Presentation Slides
Shuttling Proposal PowerPoint Presentation SlidesShuttling Proposal PowerPoint Presentation Slides
Shuttling Proposal PowerPoint Presentation Slides
 
AOL Advertising on Price/Volume Analytics for Advanced Bid Optimization and I...
AOL Advertising on Price/Volume Analytics for Advanced Bid Optimization and I...AOL Advertising on Price/Volume Analytics for Advanced Bid Optimization and I...
AOL Advertising on Price/Volume Analytics for Advanced Bid Optimization and I...
 
Communication Plan
Communication PlanCommunication Plan
Communication Plan
 
Report_Painter_Abap_rp2.ppt
Report_Painter_Abap_rp2.pptReport_Painter_Abap_rp2.ppt
Report_Painter_Abap_rp2.ppt
 
Data Visualisation and Data Analystics.pptx
Data Visualisation and Data Analystics.pptxData Visualisation and Data Analystics.pptx
Data Visualisation and Data Analystics.pptx
 
Sample Europe Shampoo Bar Market Report 2022 - Cognitive Market Research.docx
Sample Europe Shampoo Bar Market Report 2022 - Cognitive Market Research.docxSample Europe Shampoo Bar Market Report 2022 - Cognitive Market Research.docx
Sample Europe Shampoo Bar Market Report 2022 - Cognitive Market Research.docx
 
Make your data dance: PIVOT and GROUP BY in Oracle SQL
Make your data dance: PIVOT and GROUP BY in Oracle SQLMake your data dance: PIVOT and GROUP BY in Oracle SQL
Make your data dance: PIVOT and GROUP BY in Oracle SQL
 
Hoover's work gallery jan mar 2011
Hoover's work gallery jan mar 2011Hoover's work gallery jan mar 2011
Hoover's work gallery jan mar 2011
 
Portfolio_OneSheet_RP
Portfolio_OneSheet_RPPortfolio_OneSheet_RP
Portfolio_OneSheet_RP
 
Sop for Hawker Channel Sale
Sop for Hawker Channel SaleSop for Hawker Channel Sale
Sop for Hawker Channel Sale
 
The select statement
The select statementThe select statement
The select statement
 
упаковка готовая к выкладке
упаковка готовая к выкладкеупаковка готовая к выкладке
упаковка готовая к выкладке
 
Fvdi abrites commander
Fvdi abrites commanderFvdi abrites commander
Fvdi abrites commander
 
Fvdi abrites commander
Fvdi abrites commanderFvdi abrites commander
Fvdi abrites commander
 
Fvdi abrites commander
Fvdi abrites commanderFvdi abrites commander
Fvdi abrites commander
 
Cps 2011 nov overview
Cps 2011 nov overviewCps 2011 nov overview
Cps 2011 nov overview
 
Whiskey in colombia to 2016 databook
Whiskey in colombia to 2016 databookWhiskey in colombia to 2016 databook
Whiskey in colombia to 2016 databook
 

Más de Kim Berg Hansen

Más de Kim Berg Hansen (10)

External Tables - not just loading a csv file
External Tables - not just loading a csv fileExternal Tables - not just loading a csv file
External Tables - not just loading a csv file
 
When 7 bit-ascii ain't enough - about NLS, collation, charsets, unicode and s...
When 7 bit-ascii ain't enough - about NLS, collation, charsets, unicode and s...When 7 bit-ascii ain't enough - about NLS, collation, charsets, unicode and s...
When 7 bit-ascii ain't enough - about NLS, collation, charsets, unicode and s...
 
When 7-bit ASCII ain't enough - about NLS, Collation, Charsets, Unicode and such
When 7-bit ASCII ain't enough - about NLS, Collation, Charsets, Unicode and suchWhen 7-bit ASCII ain't enough - about NLS, Collation, Charsets, Unicode and such
When 7-bit ASCII ain't enough - about NLS, Collation, Charsets, Unicode and such
 
Analytic Views in Oracle 12.2
Analytic Views in Oracle 12.2Analytic Views in Oracle 12.2
Analytic Views in Oracle 12.2
 
Uses of row pattern matching
Uses of row pattern matchingUses of row pattern matching
Uses of row pattern matching
 
Read, store and create xml and json
Read, store and create xml and jsonRead, store and create xml and json
Read, store and create xml and json
 
Oracle database - Get external data via HTTP, FTP and Web Services
Oracle database - Get external data via HTTP, FTP and Web ServicesOracle database - Get external data via HTTP, FTP and Web Services
Oracle database - Get external data via HTTP, FTP and Web Services
 
Oracle database - Analytic functions - Advanced cases
Oracle database - Analytic functions - Advanced casesOracle database - Analytic functions - Advanced cases
Oracle database - Analytic functions - Advanced cases
 
Real cases of indispensability of Oracle SQL analytic functions
Real cases of indispensability of Oracle SQL analytic functionsReal cases of indispensability of Oracle SQL analytic functions
Real cases of indispensability of Oracle SQL analytic functions
 
Really using Oracle analytic SQL functions
Really using Oracle analytic SQL functionsReally using Oracle analytic SQL functions
Really using Oracle analytic SQL functions
 

Último

Just Call Vip call girls kakinada Escorts ☎️9352988975 Two shot with one girl...
Just Call Vip call girls kakinada Escorts ☎️9352988975 Two shot with one girl...Just Call Vip call girls kakinada Escorts ☎️9352988975 Two shot with one girl...
Just Call Vip call girls kakinada Escorts ☎️9352988975 Two shot with one girl...
gajnagarg
 
Call Girls Begur Just Call 👗 7737669865 👗 Top Class Call Girl Service Bangalore
Call Girls Begur Just Call 👗 7737669865 👗 Top Class Call Girl Service BangaloreCall Girls Begur Just Call 👗 7737669865 👗 Top Class Call Girl Service Bangalore
Call Girls Begur Just Call 👗 7737669865 👗 Top Class Call Girl Service Bangalore
amitlee9823
 
➥🔝 7737669865 🔝▻ Dindigul Call-girls in Women Seeking Men 🔝Dindigul🔝 Escor...
➥🔝 7737669865 🔝▻ Dindigul Call-girls in Women Seeking Men  🔝Dindigul🔝   Escor...➥🔝 7737669865 🔝▻ Dindigul Call-girls in Women Seeking Men  🔝Dindigul🔝   Escor...
➥🔝 7737669865 🔝▻ Dindigul Call-girls in Women Seeking Men 🔝Dindigul🔝 Escor...
amitlee9823
 
👉 Amritsar Call Girl 👉📞 6367187148 👉📞 Just📲 Call Ruhi Call Girl Phone No Amri...
👉 Amritsar Call Girl 👉📞 6367187148 👉📞 Just📲 Call Ruhi Call Girl Phone No Amri...👉 Amritsar Call Girl 👉📞 6367187148 👉📞 Just📲 Call Ruhi Call Girl Phone No Amri...
👉 Amritsar Call Girl 👉📞 6367187148 👉📞 Just📲 Call Ruhi Call Girl Phone No Amri...
karishmasinghjnh
 
Just Call Vip call girls Palakkad Escorts ☎️9352988975 Two shot with one girl...
Just Call Vip call girls Palakkad Escorts ☎️9352988975 Two shot with one girl...Just Call Vip call girls Palakkad Escorts ☎️9352988975 Two shot with one girl...
Just Call Vip call girls Palakkad Escorts ☎️9352988975 Two shot with one girl...
gajnagarg
 
Call Girls In Nandini Layout ☎ 7737669865 🥵 Book Your One night Stand
Call Girls In Nandini Layout ☎ 7737669865 🥵 Book Your One night StandCall Girls In Nandini Layout ☎ 7737669865 🥵 Book Your One night Stand
Call Girls In Nandini Layout ☎ 7737669865 🥵 Book Your One night Stand
amitlee9823
 
Call Girls Bommasandra Just Call 👗 7737669865 👗 Top Class Call Girl Service B...
Call Girls Bommasandra Just Call 👗 7737669865 👗 Top Class Call Girl Service B...Call Girls Bommasandra Just Call 👗 7737669865 👗 Top Class Call Girl Service B...
Call Girls Bommasandra Just Call 👗 7737669865 👗 Top Class Call Girl Service B...
amitlee9823
 
Call Girls Indiranagar Just Call 👗 9155563397 👗 Top Class Call Girl Service B...
Call Girls Indiranagar Just Call 👗 9155563397 👗 Top Class Call Girl Service B...Call Girls Indiranagar Just Call 👗 9155563397 👗 Top Class Call Girl Service B...
Call Girls Indiranagar Just Call 👗 9155563397 👗 Top Class Call Girl Service B...
only4webmaster01
 
Chintamani Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore ...
Chintamani Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore ...Chintamani Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore ...
Chintamani Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore ...
amitlee9823
 
Abortion pills in Jeddah | +966572737505 | Get Cytotec
Abortion pills in Jeddah | +966572737505 | Get CytotecAbortion pills in Jeddah | +966572737505 | Get Cytotec
Abortion pills in Jeddah | +966572737505 | Get Cytotec
Abortion pills in Riyadh +966572737505 get cytotec
 
Call Girls In Bellandur ☎ 7737669865 🥵 Book Your One night Stand
Call Girls In Bellandur ☎ 7737669865 🥵 Book Your One night StandCall Girls In Bellandur ☎ 7737669865 🥵 Book Your One night Stand
Call Girls In Bellandur ☎ 7737669865 🥵 Book Your One night Stand
amitlee9823
 
Call Girls Bannerghatta Road Just Call 👗 7737669865 👗 Top Class Call Girl Ser...
Call Girls Bannerghatta Road Just Call 👗 7737669865 👗 Top Class Call Girl Ser...Call Girls Bannerghatta Road Just Call 👗 7737669865 👗 Top Class Call Girl Ser...
Call Girls Bannerghatta Road Just Call 👗 7737669865 👗 Top Class Call Girl Ser...
amitlee9823
 
Call Girls Hsr Layout Just Call 👗 7737669865 👗 Top Class Call Girl Service Ba...
Call Girls Hsr Layout Just Call 👗 7737669865 👗 Top Class Call Girl Service Ba...Call Girls Hsr Layout Just Call 👗 7737669865 👗 Top Class Call Girl Service Ba...
Call Girls Hsr Layout Just Call 👗 7737669865 👗 Top Class Call Girl Service Ba...
amitlee9823
 
Call Girls In Hsr Layout ☎ 7737669865 🥵 Book Your One night Stand
Call Girls In Hsr Layout ☎ 7737669865 🥵 Book Your One night StandCall Girls In Hsr Layout ☎ 7737669865 🥵 Book Your One night Stand
Call Girls In Hsr Layout ☎ 7737669865 🥵 Book Your One night Stand
amitlee9823
 
Call Girls In Attibele ☎ 7737669865 🥵 Book Your One night Stand
Call Girls In Attibele ☎ 7737669865 🥵 Book Your One night StandCall Girls In Attibele ☎ 7737669865 🥵 Book Your One night Stand
Call Girls In Attibele ☎ 7737669865 🥵 Book Your One night Stand
amitlee9823
 
Just Call Vip call girls Erode Escorts ☎️9352988975 Two shot with one girl (E...
Just Call Vip call girls Erode Escorts ☎️9352988975 Two shot with one girl (E...Just Call Vip call girls Erode Escorts ☎️9352988975 Two shot with one girl (E...
Just Call Vip call girls Erode Escorts ☎️9352988975 Two shot with one girl (E...
gajnagarg
 

Último (20)

Just Call Vip call girls kakinada Escorts ☎️9352988975 Two shot with one girl...
Just Call Vip call girls kakinada Escorts ☎️9352988975 Two shot with one girl...Just Call Vip call girls kakinada Escorts ☎️9352988975 Two shot with one girl...
Just Call Vip call girls kakinada Escorts ☎️9352988975 Two shot with one girl...
 
Thane Call Girls 7091864438 Call Girls in Thane Escort service book now -
Thane Call Girls 7091864438 Call Girls in Thane Escort service book now -Thane Call Girls 7091864438 Call Girls in Thane Escort service book now -
Thane Call Girls 7091864438 Call Girls in Thane Escort service book now -
 
Call Girls Begur Just Call 👗 7737669865 👗 Top Class Call Girl Service Bangalore
Call Girls Begur Just Call 👗 7737669865 👗 Top Class Call Girl Service BangaloreCall Girls Begur Just Call 👗 7737669865 👗 Top Class Call Girl Service Bangalore
Call Girls Begur Just Call 👗 7737669865 👗 Top Class Call Girl Service Bangalore
 
➥🔝 7737669865 🔝▻ Dindigul Call-girls in Women Seeking Men 🔝Dindigul🔝 Escor...
➥🔝 7737669865 🔝▻ Dindigul Call-girls in Women Seeking Men  🔝Dindigul🔝   Escor...➥🔝 7737669865 🔝▻ Dindigul Call-girls in Women Seeking Men  🔝Dindigul🔝   Escor...
➥🔝 7737669865 🔝▻ Dindigul Call-girls in Women Seeking Men 🔝Dindigul🔝 Escor...
 
👉 Amritsar Call Girl 👉📞 6367187148 👉📞 Just📲 Call Ruhi Call Girl Phone No Amri...
👉 Amritsar Call Girl 👉📞 6367187148 👉📞 Just📲 Call Ruhi Call Girl Phone No Amri...👉 Amritsar Call Girl 👉📞 6367187148 👉📞 Just📲 Call Ruhi Call Girl Phone No Amri...
👉 Amritsar Call Girl 👉📞 6367187148 👉📞 Just📲 Call Ruhi Call Girl Phone No Amri...
 
Just Call Vip call girls Palakkad Escorts ☎️9352988975 Two shot with one girl...
Just Call Vip call girls Palakkad Escorts ☎️9352988975 Two shot with one girl...Just Call Vip call girls Palakkad Escorts ☎️9352988975 Two shot with one girl...
Just Call Vip call girls Palakkad Escorts ☎️9352988975 Two shot with one girl...
 
Call Girls In Nandini Layout ☎ 7737669865 🥵 Book Your One night Stand
Call Girls In Nandini Layout ☎ 7737669865 🥵 Book Your One night StandCall Girls In Nandini Layout ☎ 7737669865 🥵 Book Your One night Stand
Call Girls In Nandini Layout ☎ 7737669865 🥵 Book Your One night Stand
 
Call Girls Bommasandra Just Call 👗 7737669865 👗 Top Class Call Girl Service B...
Call Girls Bommasandra Just Call 👗 7737669865 👗 Top Class Call Girl Service B...Call Girls Bommasandra Just Call 👗 7737669865 👗 Top Class Call Girl Service B...
Call Girls Bommasandra Just Call 👗 7737669865 👗 Top Class Call Girl Service B...
 
Discover Why Less is More in B2B Research
Discover Why Less is More in B2B ResearchDiscover Why Less is More in B2B Research
Discover Why Less is More in B2B Research
 
Call Girls Indiranagar Just Call 👗 9155563397 👗 Top Class Call Girl Service B...
Call Girls Indiranagar Just Call 👗 9155563397 👗 Top Class Call Girl Service B...Call Girls Indiranagar Just Call 👗 9155563397 👗 Top Class Call Girl Service B...
Call Girls Indiranagar Just Call 👗 9155563397 👗 Top Class Call Girl Service B...
 
Chintamani Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore ...
Chintamani Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore ...Chintamani Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore ...
Chintamani Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore ...
 
Abortion pills in Jeddah | +966572737505 | Get Cytotec
Abortion pills in Jeddah | +966572737505 | Get CytotecAbortion pills in Jeddah | +966572737505 | Get Cytotec
Abortion pills in Jeddah | +966572737505 | Get Cytotec
 
Call Girls In Bellandur ☎ 7737669865 🥵 Book Your One night Stand
Call Girls In Bellandur ☎ 7737669865 🥵 Book Your One night StandCall Girls In Bellandur ☎ 7737669865 🥵 Book Your One night Stand
Call Girls In Bellandur ☎ 7737669865 🥵 Book Your One night Stand
 
Call Girls Bannerghatta Road Just Call 👗 7737669865 👗 Top Class Call Girl Ser...
Call Girls Bannerghatta Road Just Call 👗 7737669865 👗 Top Class Call Girl Ser...Call Girls Bannerghatta Road Just Call 👗 7737669865 👗 Top Class Call Girl Ser...
Call Girls Bannerghatta Road Just Call 👗 7737669865 👗 Top Class Call Girl Ser...
 
Call Girls Hsr Layout Just Call 👗 7737669865 👗 Top Class Call Girl Service Ba...
Call Girls Hsr Layout Just Call 👗 7737669865 👗 Top Class Call Girl Service Ba...Call Girls Hsr Layout Just Call 👗 7737669865 👗 Top Class Call Girl Service Ba...
Call Girls Hsr Layout Just Call 👗 7737669865 👗 Top Class Call Girl Service Ba...
 
Call Girls In Hsr Layout ☎ 7737669865 🥵 Book Your One night Stand
Call Girls In Hsr Layout ☎ 7737669865 🥵 Book Your One night StandCall Girls In Hsr Layout ☎ 7737669865 🥵 Book Your One night Stand
Call Girls In Hsr Layout ☎ 7737669865 🥵 Book Your One night Stand
 
Detecting Credit Card Fraud: A Machine Learning Approach
Detecting Credit Card Fraud: A Machine Learning ApproachDetecting Credit Card Fraud: A Machine Learning Approach
Detecting Credit Card Fraud: A Machine Learning Approach
 
Digital Advertising Lecture for Advanced Digital & Social Media Strategy at U...
Digital Advertising Lecture for Advanced Digital & Social Media Strategy at U...Digital Advertising Lecture for Advanced Digital & Social Media Strategy at U...
Digital Advertising Lecture for Advanced Digital & Social Media Strategy at U...
 
Call Girls In Attibele ☎ 7737669865 🥵 Book Your One night Stand
Call Girls In Attibele ☎ 7737669865 🥵 Book Your One night StandCall Girls In Attibele ☎ 7737669865 🥵 Book Your One night Stand
Call Girls In Attibele ☎ 7737669865 🥵 Book Your One night Stand
 
Just Call Vip call girls Erode Escorts ☎️9352988975 Two shot with one girl (E...
Just Call Vip call girls Erode Escorts ☎️9352988975 Two shot with one girl (E...Just Call Vip call girls Erode Escorts ☎️9352988975 Two shot with one girl (E...
Just Call Vip call girls Erode Escorts ☎️9352988975 Two shot with one girl (E...
 

Data twisting

  • 1. BASEL BERN BRUGG DÜSSELDORF FRANKFURT A.M. FREIBURG I.BR. GENF HAMBURG KOPENHAGEN LAUSANNE MÜNCHEN STUTTGART WIEN ZÜRICH Data Twisting OUGN Spring Seminar 10-12 March 2016 Kim Berg Hansen Senior Consultant
  • 2. • Danish geek • SQL & PL/SQL developer since 2000 • Developer at Trivadis AG since 2016 http://www.trivadis.dk • Oracle Certified Expert in SQL • Oracle ACE • Blogger at http://www.kibeha.dk • SQL quizmaster at http://plsqlchallenge.oracle.com • Likes to cook • Reads sci-fi • Chairman of local chapter of Danish Beer Enthusiasts About me Data Twisting2 3/30/2016
  • 3. About Trivadis Data Twisting3 3/30/2016 Trivadis is a market leader in IT consulting, system integration, solution engineering and the provision of IT services focusing on and technologies in Switzerland, Germany, Austria and Denmark. We offer our services in the following strategic business fields: Trivadis Services takes over the interacting operation of your IT systems. O P E R A T I O N
  • 4. COPENHAGEN MUNICH LAUSANNE BERN ZURICH BRUGG GENEVA HAMBURG DÜSSELDORF FRANKFURT STUTTGART FREIBURG BASEL VIENNA With over 600 specialists and IT experts in your region Data Twisting4 3/30/2016 14 Trivadis branches and more than 600 employees 260 Service Level Agreements Over 4,000 training participants Research and development budget: EUR 5.0 million Financially self-supporting and sustainably profitable Experience from more than 1,900 projects per year at over 800 customers
  • 5. Agenda for Data Twisting Data Twisting5 3/30/2016 1. Why do we need to Twist, Shake, Rattle ‘n‘ Roll 2. Twist UNPIVOT with single or multi-column dimensions Unpivoting with row generators 3. Shake PIVOT with single or multi-column dimensions, with or without grouping Pivoting with GROUP BY and CASE 4. Rattle Turning delimited data into columns and rows ODCI dynamic table function parser 5. Roll LISTAGG to turn rows into delimited data Alternative methods for string aggregation 6. Coda
  • 6. Data Twisting6 3/30/2016 Twist, Shake, Rattle ’n’ Roll
  • 7. EMEA AMER ASOC Beer WineWine Twist Columns to Rows Data Twisting7 3/30/2016 Category Region Sales Beer Wine 200000 10000 150000 25000 225000 17500 EMEA AMER ASOC Beer
  • 8. EMEA AMER ASOC Beer Wine Wine Shake Rows to Columns Data Twisting8 3/30/2016 Category Region Sales Beer Wine 200000 10000 150000 25000 225000 EMEA AMER ASOCBeer 17500
  • 9. Beer Wine Rattle Delimited Data to Columns Data Twisting9 3/30/2016 CategoryEMEAAMER 200000 10000 150000 25000 225000 17500 ASOCCategory;EMEA;AMER;ASOC Beer;200000;150000;225000 Wine;10000;25000;17500
  • 10. Rattle Delimited Data to Rows Data Twisting10 3/30/2016 Category BeerBeer Type PilsnerBeer WineWine AleStout RedChampagne TypeList Pilsner;Ale;Stout Red;Champagne
  • 11. TypeList Pilsner;Ale;Stout Red;Champagne Roll Rows to Delimited Data Data Twisting11 3/30/2016 Category Beer Beer Beer Wine Wine Type Pilsner Ale Stout Red Champagne
  • 13. Single dimension and measure Data Twisting13 3/30/2016 create table sales1 ( category varchar2(10) , emea number , amer number , asoc number ); insert into sales1 values ('Beer', 200000, 150000, 225000); insert into sales1 values ('Wine', 10000, 25000, 17500); Table of beverage sales with columns per region
  • 14. Single dimension and measure Data Twisting14 3/30/2016 select category, region, sales from sales1 unpivot ( sales for region in ( emea as 'EMEA' , amer as 'AMER' , asoc as 'ASOC' ) ) order by category, region; UNPIVOT create dimension REGION and measure SALES CATEGORY REGI SALES ---------- ---- ---------- Beer AMER 150000 Beer ASOC 225000 Beer EMEA 200000 Wine AMER 25000 Wine ASOC 17500 Wine EMEA 10000
  • 15. Single dimension and measure Data Twisting15 3/30/2016 select category , case n# when 1 then 'EMEA' when 2 then 'AMER' when 3 then 'ASOC' end region , case n# when 1 then emea when 2 then amer when 3 then asoc end sales from sales1 cross join ( select level n# from dual connect by level <= 3 ) order by category, region; Generate 3 rows - Cartesian join – CASE logic for dimension and measure CATEGORY REGI SALES ---------- ---- ---------- Beer AMER 150000 Beer ASOC 225000 Beer EMEA 200000 Wine AMER 25000 Wine ASOC 17500 Wine EMEA 10000
  • 16. Single dimension and measure Data Twisting16 3/30/2016 with r (region) as ( select 'EMEA' from dual union all select 'AMER' from dual union all select 'ASOC' from dual ) select category, region , case region when 'EMEA' then emea when 'AMER' then amer when 'ASOC' then asoc end sales from sales1 cross join r order by category, region; Generate 3 rows with dimension - Cartesian join – CASE logic for measure CATEGORY REGI SALES ---------- ---- ---------- Beer AMER 150000 Beer ASOC 225000 Beer EMEA 200000 Wine AMER 25000 Wine ASOC 17500 Wine EMEA 10000
  • 17. Multiple dimensions and measures Data Twisting17 3/30/2016 create table sales2 ( category varchar2(10) , dk_b2b_qty number , dk_b2b_amount number , dk_b2c_qty number , dk_b2c_amount number , uk_b2b_qty number , uk_b2b_amount number , uk_b2c_qty number , uk_b2c_amount number ); insert into sales2 values ('Beer', 500, 5000, 250, 2500, 100, 1000, 200, 2000); insert into sales2 values ('Wine', 150, 3000, 200, 4000, 400, 8000, 300, 6000); Table of beverage sales with qty and amount columns per country and channel
  • 18. Multiple dimensions and measures Data Twisting18 3/30/2016 select category, country, channel, qty, amount from sales2 unpivot ( ( qty, amount ) for ( country, channel ) in ( (dk_b2b_qty, dk_b2b_amount) as ('DK', 'B2B') , (dk_b2c_qty, dk_b2c_amount) as ('DK', 'B2C') , (uk_b2b_qty, uk_b2b_amount) as ('UK', 'B2B') , (uk_b2c_qty, uk_b2c_amount) as ('UK', 'B2C') ) ) order by category, country, channel; UNPIVOT create dimensions COUNTRY, CHANNEL and measures QTY, AMOUNT CATEGORY CO CHA QTY AMOUNT ---------- -- --- ----- ------- Beer DK B2B 500 5000 Beer DK B2C 250 2500 Beer UK B2B 100 1000 Beer UK B2C 200 2000 Wine DK B2B 150 3000 Wine DK B2C 200 4000 Wine UK B2B 400 8000 Wine UK B2C 300 6000
  • 19. Single dimension and multiple measures Data Twisting19 3/30/2016 select category, country_and_channel, qty, amount from sales2 unpivot ( ( qty, amount ) for ( country_and_channel ) in ( (dk_b2b_qty, dk_b2b_amount) as ('DK_B2B') , (dk_b2c_qty, dk_b2c_amount) as ('DK_B2C') , (uk_b2b_qty, uk_b2b_amount) as ('UK_B2B') , (uk_b2c_qty, uk_b2c_amount) as ('UK_B2C') ) ) order by category, country_and_channel; UNPIVOT create dimension COUNTRY_AND_CHANNEL - measures QTY, AMOUNT CATEGORY COUNTR QTY AMOUNT ---------- ------ ----- ------- Beer DK_B2B 500 5000 Beer DK_B2C 250 2500 Beer UK_B2B 100 1000 Beer UK_B2C 200 2000 Wine DK_B2B 150 3000 Wine DK_B2C 200 4000 Wine UK_B2B 400 8000 Wine UK_B2C 300 6000
  • 20. Multiple dimensions and single measure Data Twisting20 3/30/2016 select category, country, channel, amount from sales2 unpivot ( ( amount ) for ( country, channel ) in ( (dk_b2b_amount) as ('DK', 'B2B') , (dk_b2c_amount) as ('DK', 'B2C') , (uk_b2b_amount) as ('UK', 'B2B') , (uk_b2c_amount) as ('UK', 'B2C') ) ) order by category, country, channel; UNPIVOT create dimensions COUNTRY, CHANNEL - measure AMOUNT CATEGORY CO CHA AMOUNT ---------- -- --- ---------- Beer DK B2B 5000 Beer DK B2C 2500 Beer UK B2B 1000 Beer UK B2C 2000 Wine DK B2B 3000 Wine DK B2C 4000 Wine UK B2B 8000 Wine UK B2C 6000
  • 22. Single dimension and measure Data Twisting22 3/30/2016 create table sales3 ( category varchar2(10) , region varchar2(10) , sales number ); insert into sales3 values ('Beer', 'EMEA', 200000); insert into sales3 values ('Beer', 'AMER', 150000); insert into sales3 values ('Beer', 'ASOC', 225000); insert into sales3 values ('Wine', 'EMEA', 10000); insert into sales3 values ('Wine', 'AMER', 25000); insert into sales3 values ('Wine', 'ASOC', 17500); Table of beverage sales per region
  • 23. Single dimension and measure Data Twisting23 3/30/2016 select category, emea, amer, asoc from sales3 pivot ( sum(sales) for region in ( 'EMEA' as emea , 'AMER' as amer , 'ASOC' as asoc ) ) order by category; PIVOT create 3 columns for 3 dimension values and 1 measure CATEGORY EMEA AMER ASOC ---------- ------- ------- ------- Beer 200000 150000 225000 Wine 10000 25000 17500
  • 24. Single dimension and measure Data Twisting24 3/30/2016 select category , sum(case region when 'EMEA' then sales end) as emea , sum(case region when 'AMER' then sales end) as amer , sum(case region when 'ASOC' then sales end) as asoc from sales3 group by category order by category; GROUP BY using CASE statement within SUM for each of the 3 dimension values CATEGORY EMEA AMER ASOC ---------- ------- ------- ------- Beer 200000 150000 225000 Wine 10000 25000 17500
  • 25. Single dimension and measure Data Twisting25 3/30/2016 insert into sales3 values ('Beer', 'AMER', 25000); commit; select category, emea, amer, asoc from sales3 pivot ( sum(sales) for region in ( 'EMEA' as emea , 'AMER' as amer , 'ASOC' as asoc ) ) order by category; Aggregations used for non-unique dimensions CATEGORY EMEA AMER ASOC ---------- ------- ------- ------- Beer 200000 175000 225000 Wine 10000 25000 17500
  • 26. Single dimension and multiple measures Data Twisting26 3/30/2016 select * from sales3 pivot ( sum(sales) , count(*) for region in ( 'EMEA' as emea , 'AMER' as amer , 'ASOC' as asoc ) ) order by category; Columns are named <dim>_<measure> , so problem if no measure aliases ERROR at line 1: ORA-00918: column ambiguously defined
  • 27. Single dimension and multiple measures Data Twisting27 3/30/2016 CATEGORY EMEA_SALE EMEA_CNT AMER_SALE AMER_CNT ASOC_SALE ASOC_CNT -------- --------- -------- --------- -------- --------- -------- Beer 200000 1 175000 2 225000 1 Wine 10000 1 25000 1 17500 1 select category, emea_sale, emea_cnt, amer_sale, amer_cnt, asoc_sale, asoc_cnt from sales3 pivot ( sum(sales) as sale, count(*) as cnt for region in ( 'EMEA' as emea, 'AMER' as amer, 'ASOC' as asoc ) ) order by category; With measure aliases we get 3x2 columns named <dim>_<measure> combinations
  • 28. Multiple dimensions and measures Data Twisting28 3/30/2016 create table sales4 ( category varchar2(10) , country varchar2(10) , channel varchar2(10) , qty number , amount number ); insert into sales4 values('Beer', 'DK', 'B2B', 500, 5000); insert into sales4 values('Beer', 'DK', 'B2C', 250, 2500); insert into sales4 values('Beer', 'UK', 'B2B', 100, 1000); insert into sales4 values('Beer', 'UK', 'B2C', 200, 2000); insert into sales4 values('Wine', 'DK', 'B2B', 150, 3000); insert into sales4 values('Wine', 'DK', 'B2C', 200, 4000); insert into sales4 values('Wine', 'UK', 'B2B', 400, 8000); insert into sales4 values('Wine', 'UK', 'B2C', 300, 6000); Table of beverage sales measured in qty and amount per country and channel
  • 29. Multiple dimensions and measures Data Twisting29 3/30/2016 CATEGORY DK_B2B_QTY DK_B2B_AMOUNT DK_B2C_QTY DK_B2C_AMOUNT UK_B2B_QTY UK_B2B_AMOUNT UK_B2C_QTY UK_B2C_AMOUNT ---------- ---------- ------------- ---------- ------------- ---------- ------------- ---------- ------------- Beer 500 5000 250 2500 100 1000 200 2000 Wine 150 3000 200 4000 400 8000 300 6000 select category, dk_b2b_qty, dk_b2b_amount, dk_b2c_qty, dk_b2c_amount , uk_b2b_qty, uk_b2b_amount, uk_b2c_qty, uk_b2c_amount from sales4 pivot ( sum(qty) as qty, sum(amount) as amount for ( country, channel ) in ( ('DK', 'B2B') as dk_b2b , ('DK', 'B2C') as dk_b2c , ('UK', 'B2B') as uk_b2b , ('UK', 'B2C') as uk_b2c ) ) order by category; With dimension and measure aliases we get (2x2)x2 columns
  • 31. Delimited data to columns Data Twisting31 3/30/2016 create table sales5 ( txt varchar2(100) ); insert into sales5 values ('Beer;200000;150000;225000'); insert into sales5 values ('Wine;10000;25000;17500'); Table of beverage sales as semi-colon separated text
  • 32. Delimited data to columns Data Twisting32 3/30/2016 CATEGORY EMEA AMER ASOC -------- ------ ------ ------ Beer 200000 150000 225000 Wine 10000 25000 17500 select substr(txt, 1, instr(txt,';') - 1) category , substr( txt, instr(txt,';') + 1, instr(txt,';',1,2) - instr(txt,';') -1 ) emea , substr( txt, instr(txt,';',1,2) + 1, instr(txt,';',1,3) - instr(txt,';',1,2) - 1 ) amer , substr(txt, instr(txt,';',1,3) + 1) asoc from sales5 order by category; Using SUBSTR and INSTR
  • 33. Delimited data to columns Data Twisting33 3/30/2016 CATEGORY EMEA AMER ASOC -------- ------ ------ ------ Beer 200000 150000 225000 Wine 10000 25000 17500 select regexp_substr(txt, '[^;]+', 1, 1) category , regexp_substr(txt, '[^;]+', 1, 2) emea , regexp_substr(txt, '[^;]+', 1, 3) amer , regexp_substr(txt, '[^;]+', 1, 4) asoc from sales5 order by category; Using REGEXP_SUBSTR
  • 34. Delimited data to rows Data Twisting34 3/30/2016 create table beverages1 ( category varchar2(10) , typelist varchar2(100) ); insert into beverages1 values ('Beer', 'Pilsner;Ale;Stout'); insert into beverages1 values ('Wine', 'Red;Champagne'); Table of beverage types as semi-colon separated text
  • 35. Delimited data to rows Data Twisting35 3/30/2016 create type beverage_collection_type as table of varchar2(10); / create or replace function beverage_typelist_to_coll ( typelist in beverages1.typelist%type ) return beverage_collection_type pipelined is list_len pls_integer; from_pos pls_integer; to_pos pls_integer; begin list_len := length(typelist); from_pos := 1; loop to_pos := nvl(nullif(instr(typelist, ';', from_pos), 0), list_len+1); pipe row (substr(typelist, from_pos, to_pos-from_pos)); exit when to_pos > list_len; from_pos := to_pos + 1; end loop; end beverage_typelist_to_coll; / Collection type and pipelined function to parse string and pipe out collection
  • 36. Delimited data to rows Data Twisting36 3/30/2016 select category , column_value as beverage_type from beverages1 , table(beverage_typelist_to_coll(typelist)) order by category, beverage_type; Use pipelined table function within TABLE CATEGORY BEVERAGE_T -------- ---------- Beer Ale Beer Pilsner Beer Stout Wine Champagne Wine Red
  • 37. Delimited data to rows Data Twisting37 3/30/2016 select category , regexp_substr(typelist, '[^;]+', 1, sub#) beverage_type from beverages1 cross join lateral ( select level sub# from dual connect by level <= regexp_count(typelist, ';') + 1 ) order by category, beverage_type; Generate count of delimiters + 1 rows per category (note: LATERAL requires 12c) CATEGORY BEVERAGE_T -------- ---------- Beer Ale Beer Pilsner Beer Stout Wine Champagne Wine Red
  • 38. Delimited/structured data to rows and columns Data Twisting38 3/30/2016 create table beverages2 ( category varchar2(10) , typelist varchar2(100) ); insert into beverages2 values ('Beer', 'Pilsner|Light;Ale|Medium;Stout|Dark'); insert into beverages2 values ('Wine', 'Red|Red;Champagne|Clear'); Table of beverage types and colors as semi-colon and pipe separated text
  • 39. Delimited/structured data to rows and columns Data Twisting39 3/30/2016 create or replace type delimited_col_row as object ( {globals} , static function parser( {params} ) return anydataset pipelined using delimited_col_row , static function odcitabledescribe( {params} ) return number , static function odcitableprepare( {params} ) return number , static function odcitablestart( {params} ) return number , member function odcitablefetch( {params} ) return number , member function odcitableclose( {params} ) return number ) / create or replace type body delimited_col_row as {implementation} end; / Object type implementing ODCI functions (complete code in script: http://bit.ly/kibeha_datatwist_sql)
  • 40. Delimited/structured data to rows and columns Data Twisting40 3/30/2016 select category, beverage_type, color from beverages2 , table( delimited_col_row.parser( typelist , 'BEVERAGE_TYPE|VARCHAR2(10);COLOR|VARCHAR2(10)' , '|' , ';' ) ) type_and_color order by category, beverage_type; Use ODCI parser function within TABLE – Column definition string must be a literal CATEGORY BEVERAGE_T COLOR -------- ---------- ---------- Beer Ale Medium Beer Pilsner Light Beer Stout Dark Wine Champagne Clear Wine Red Red
  • 42. Rows to delimited data Data Twisting42 3/30/2016 create table beverages3 ( category varchar2(10) , beverage_type varchar2(10) ); insert into beverages3 values ('Beer', 'Pilsner'); insert into beverages3 values ('Beer', 'Ale'); insert into beverages3 values ('Beer', 'Stout'); insert into beverages3 values ('Wine', 'Red'); insert into beverages3 values ('Wine', 'Champagne'); Table of beverage types per category
  • 43. Rows to delimited data Data Twisting43 3/30/2016 select category , listagg(beverage_type, ';') within group ( order by beverage_type ) typelist from beverages3 group by category order by category; LISTAGG built-in aggregate function (11.2) CATEGORY TYPELIST -------- -------------------- Beer Ale;Pilsner;Stout Wine Champagne;Red
  • 44. Rows to delimited data Data Twisting44 3/30/2016 create type beverage_collection_type as table of varchar2(10); / create or replace function beverage_typecoll_to_string ( typecoll in beverage_collection_type ) return varchar2 is type_string varchar2(4000); begin for idx in typecoll.first .. typecoll.last loop if idx = typecoll.first then type_string := typecoll(idx); else type_string := type_string || ';' || typecoll(idx); end if; end loop; return type_string; end beverage_typecoll_to_string; / Create collection type and a function to turn collection into delimited string
  • 45. Rows to delimited data Data Twisting45 3/30/2016 select category , beverage_typecoll_to_string( cast( collect( beverage_type order by beverage_type ) as beverage_collection_type ) ) typelist from beverages3 group by category order by category; Use COLLECT to aggregate into collection, then call function to create string CATEGORY TYPELIST -------- -------------------- Beer Ale;Pilsner;Stout Wine Champagne;Red
  • 46. Rows to delimited data Data Twisting46 3/30/2016 create or replace type string_agg_type as object( total varchar2(4000), static function ODCIAggregateInitialize( {params} ) return number, member function ODCIAggregateIterate( {params} ) return number, member function ODCIAggregateTerminate( {params} ) return number, member function ODCIAggregateMerge( {params} ) return number ); / create or replace type body string_agg_type {implementation} end; / create or replace function stragg( input varchar2 ) return varchar2 parallel_enable aggregate using string_agg_type; / Tom Kyte STRAGG function using ODCI implementation of user aggregate function https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:2196162600402
  • 47. Rows to delimited data Data Twisting47 3/30/2016 select category , stragg(beverage_type) typelist from beverages3 group by category order by category; Use STRAGG like any aggregate – Note unlike LISTAGG this can not ORDER BY CATEGORY TYPELIST -------- -------------------- Beer Pilsner;Stout;Ale Wine Red;Champagne
  • 49. We Can Boogie Data Twisting49 3/30/2016 Twist Columns to Rows – UNPIVOT or dummy row generators Shake Rows to Columns – PIVOT or GROUP BY with CASE Rattle Delimited Data to Columns or Rows – Parse delimited data Roll Rows to Delimited Data – LISTAGG or other string aggregation techniques Boogie! 
  • 50. Data Twisting50 3/30/2016 Links This presentation PowerPoint http://bit.ly/kibeha_datatwist_pptx Script with all examples from this presentation http://bit.ly/kibeha_datatwist_sql
  • 51. Questions & Answers Kim Berg Hansen Senior Consultant kim.berghansen@trivadis.com 3/30/2016 Data Twisting51 http://bit.ly/kibeha_datatwist_pptx http://bit.ly/kibeha_datatwist_sql