Managing recursive, tree-like data structures  with  Firebird Frank Ingermann
Welcome to this session ! … say Sparkies I and III
This session is... a piece of cake! about
Session overview <ul><li>Short intro to Trees in DBs </li></ul><ul><li>Part 1:  Recursive StoredProcs </li></ul><ul><li>Pa...
What is a tree? <ul><li>It has a  single   Root </li></ul><ul><li>It has  forks  or  branches  ( Nodes ) </li></ul><ul><li...
What is a tree? <ul><li>It has a  single   Root </li></ul><ul><li>It has  forks  or  branches  ( Nodes ) </li></ul><ul><li...
Tree terms: Root, Nodes, Leafs <ul><li>ROOT node </li></ul><ul><ul><li>„ upper end“,  has  no  parent node </li></ul></ul>...
Recursion types <ul><li>„ Top-Down“   recursion </li></ul><ul><ul><li>Starts with  top  node, traverses  all childs  („wal...
Tree „Cardinality“ <ul><li>BINARY  trees:   </li></ul><ul><ul><li>each node has  max .  2  child nodes  <n max >=2 </li></...
Tree „Health“  (esp. in search trees) <ul><li>„ healthy“  trees:   </li></ul><ul><ul><li>Are as „flat“ as possible, well-„...
Relations of nodes in trees <ul><li>Owner   or   Containing   relation </li></ul><ul><ul><li>e.g.  File System :  </li></u...
Tree types <ul><li>„ homogeneous“   trees:  </li></ul><ul><li>all nodes:  same  type </li></ul><ul><li>(SQL : all node dat...
Strategies for storing trees <ul><li>Store a  Parent ref. (PK/ID)  in each node/leaf </li></ul><ul><ul><li>Classic approac...
Retrieving Trees from a DB <ul><li>Client-Side  recursion </li></ul><ul><ul><li>SELECT  parent node </li></ul></ul><ul><ul...
Pros  of Client-Side recursion <ul><li>Client has  full  control </li></ul><ul><ul><li>What  and  How  is traversed </li><...
Why we  don‘t want  client-side  rec.: <ul><li>Many  Prepares  on  Server side (calculating plans etc. costs  Server time ...
Part 1 <ul><li>Recursive </li></ul><ul><li>Stored  </li></ul><ul><li>Procedures </li></ul>
Stored Procedures <ul><li>Can call  other  Stored Procedures (including  themselves ) </li></ul><ul><li>„ Direct“   recurs...
Traversing trees with Selectable SPs <ul><li>Recursive  Top-Down  SP outline: </li></ul><ul><li>SELECT   parent  node‘s da...
Recursive SPs:  Pros  and  Cons <ul><li>Pros: </li></ul><ul><ul><li>Recursion on  Server  side,  few round-trips  </li></u...
Part 2 <ul><li>Nested Sets </li></ul>Take some  sets… … and another set… -> „S1“ -> „S2“ … then  nest  S1 into S2… … then,...
Nested Sets: Intro same data as  Nested Sets : „ classical“ tree: Nested Sets  are all about Containment ! … and NO, this ...
Nested Sets: different views
Nested Sets:  L  and  R  values L R L R L R L R L R
Nested Sets: Rules for  L  and  R <ul><li>L  value of  ROOT ==   1   (ex def.) </li></ul><ul><li>L   <   R   (for  all  no...
Nested Sets: Storage in DB
INSERT s in Nested Sets
DELETE s in Nested Sets
Moving nodes  in Nested Sets
<ul><li>Pros: </li></ul><ul><ul><li>Good for static (read-only),    Owner/Containing   type trees </li></ul></ul><ul><ul><...
Part 3 <ul><li>Recursive </li></ul><ul><li>CTEs </li></ul><ul><li>(Common Table Expressions) </li></ul>
Recursive CTEs:  Pros  and  Cons <ul><li>Cons: </li></ul><ul><ul><li>Client must  know  and  understand     tree structure...
Recursive CTEs:  Pros  and  Cons <ul><li>Pros: </li></ul><ul><ul><li>Server-side  recursion  </li></ul></ul><ul><ul><li>fa...
„ normal“ CTEs:  Intro <ul><li>WITH   <alias>   AS  (  <select_expression>  )  --„preamble“ SELECT  <…>    FROM   <alias> ...
Recursive CTEs:  Intro <ul><li>a  CTE  is an „ inline   VIEW“  inside a  SELECT </li></ul><ul><li>a  recursive   CTE   („v...
Recursive CTEs:  basic structure <ul><li>WITH   RECURSIVE   <cte_alias>   AS   ( </li></ul><ul><li>SELECT   <parent data> ...
Traversing trees with recursive CTEs <ul><li>WITH   RECURSIVE   fs_tree  AS ( </li></ul><ul><li>SELECT  id, filename  FROM...
Server processing of rec. CTEs  I <ul><li>WITH RECURSIVE  <x>  AS </li></ul><ul><li>(  SELECT   <parent>  --  PA </li></ul...
Server processing of rec. CTEs  II <ul><li>Execute  PA  („anchor query“) </li></ul><ul><li>For each  result row  RR :  SEN...
Recursive results -> „flat“ result set this slide ©  Vladyslav Khorsun - thanks, Vlad !   A Ch
Ordering Children in recursive CTEs <ul><li>The Problem: </li></ul><ul><ul><li>Because of the  UNION ,  you can‘t have an ...
Ordering Children in recursive CTEs <ul><li>Solution A  (Fb <x>) </li></ul><ul><li>Use  DEPTH FIRST BY <columns>  clause  ...
Ordering Children in recursive CTEs <ul><li>„ Solution“ B  (Fb 3) : Use a  Window Function : with  rcte  as (   select … f...
Ordering Children in recursive CTEs <ul><li>Solution C: </li></ul><ul><li>Use a  SELECTABLE SP  as Child Select </li></ul>...
Ordering Children in recursive CTEs <ul><li>Solution D: </li></ul><ul><li>Construct a  sort path  </li></ul><ul><ul><ul><l...
Part 4 <ul><li>„ Real world“ </li></ul><ul><li>CTE Examples </li></ul>
„ Fun“ with recursive CTEs <ul><li>Let‘s bake some </li></ul><ul><li>marble cake! </li></ul>Vanilla  cake mixture Chocolat...
Ingredients (RAW MATerials) <ul><li>Yolk (egg) </li></ul><ul><li>Sugar </li></ul><ul><li>Flour </li></ul><ul><li>Butter </...
Shugga  baby! <ul><li>This cake  has 5  sub-recipes </li></ul><ul><li>Each has a different  %  of  sugar </li></ul><ul><li...
<ul><li>that‘s about it… </li></ul><ul><li>Thank you for your attention! </li></ul>Questions ? Frank Ingermann [email_addr...
Upcoming SlideShare
Loading in …5
×

Handling tree structures — recursive SPs, nested sets, recursive CTEs

3,751 views

Published on

How to work with tree structures in Firebird SQL

Published in: Technology, Business
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,751
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
25
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Handling tree structures — recursive SPs, nested sets, recursive CTEs

  1. 1. Managing recursive, tree-like data structures with Firebird Frank Ingermann
  2. 2. Welcome to this session ! … say Sparkies I and III
  3. 3. This session is... a piece of cake! about
  4. 4. Session overview <ul><li>Short intro to Trees in DBs </li></ul><ul><li>Part 1: Recursive StoredProcs </li></ul><ul><li>Part 2: Nested Sets </li></ul><ul><li>Part 3: Recursive CTEs </li></ul><ul><li>Part 4: „real- world “ examples </li></ul>
  5. 5. What is a tree? <ul><li>It has a single Root </li></ul><ul><li>It has forks or branches ( Nodes ) </li></ul><ul><li>Branches end up in Leafs (most of the time…) </li></ul>
  6. 6. What is a tree? <ul><li>It has a single Root </li></ul><ul><li>It has forks or branches ( Nodes ) </li></ul><ul><li>Branches end up in Leafs (most of the time…) </li></ul>
  7. 7. Tree terms: Root, Nodes, Leafs <ul><li>ROOT node </li></ul><ul><ul><li>„ upper end“, has no parent node </li></ul></ul><ul><li>NODE(s) </li></ul><ul><ul><li>Can have 0..1 PARENT node </li></ul></ul><ul><ul><li>Can have 0.. n CHILD nodes </li></ul></ul><ul><li>LEAF node(s) </li></ul><ul><ul><li>A node with no child nodes („lower end“) </li></ul></ul><ul><li>Leafs and nodes can have siblings ( same parent node = „brothers/sisters“ ) </li></ul>Root node Node Leaf Leaf
  8. 8. Recursion types <ul><li>„ Top-Down“ recursion </li></ul><ul><ul><li>Starts with top node, traverses all childs („walk the tree“) „ visits“ each child node once </li></ul></ul><ul><li>„ Bottom-Up“ recursion </li></ul><ul><ul><li>Starts with (any) child node, walks up the tree until ROOT </li></ul></ul><ul><ul><li>Can usually be done with iteration </li></ul></ul>
  9. 9. Tree „Cardinality“ <ul><li>BINARY trees: </li></ul><ul><ul><li>each node has max . 2 child nodes <n max >=2 </li></ul></ul><ul><ul><li>red-black trees, (balanced) search trees (AVL-trees: Adelson-Velskii & Landis, 1962) </li></ul></ul><ul><li>N- or Bayer trees: </li></ul><ul><ul><li>each node has 0..<n> child nodes (<n>=cardinality) </li></ul></ul><ul><ul><li>typical structure for e.g. File Systems </li></ul></ul><ul><li>Binary trees are a Special Case of N-Trees </li></ul>
  10. 10. Tree „Health“ (esp. in search trees) <ul><li>„ healthy“ trees: </li></ul><ul><ul><li>Are as „flat“ as possible, well-„ balanced “ </li></ul></ul><ul><ul><li>fewer recursion levels -> faster traversal </li></ul></ul><ul><li>„ unhealthy“ trees: </li></ul><ul><ul><li>can degenerate to lists </li></ul></ul><ul><ul><li>make a lot of work to get to few data </li></ul></ul><ul><li>Recursion is always slower then iteration </li></ul>8 nodes, 8 levels deep 31 nodes, 4 levels deep
  11. 11. Relations of nodes in trees <ul><li>Owner or Containing relation </li></ul><ul><ul><li>e.g. File System : </li></ul></ul><ul><ul><li>each file is „ owned“ by the directory it‘s in </li></ul></ul><ul><ul><li>each file can only be in one directory </li></ul></ul><ul><ul><li>deleting the directory deletes all files in it </li></ul></ul><ul><li>Referencing relation (links) </li></ul><ul><ul><li>e.g. Recipe Database : </li></ul></ul><ul><ul><li>each recipe can reference 0..n sub-recipes </li></ul></ul><ul><ul><li>One sub-recipe can be referenced by many master recipes </li></ul></ul><ul><ul><li>deleting a master recipe will not delete its sub-recipes </li></ul></ul><ul><li>A node can reference a node in another tree </li></ul>
  12. 12. Tree types <ul><li>„ homogeneous“ trees: </li></ul><ul><li>all nodes: same type </li></ul><ul><li>(SQL : all node data comes from one table) </li></ul><ul><li>„ heterogeneous“ trees: </li></ul><ul><li>nodes can have different data- or record types </li></ul><ul><li>(SQL : data can come from various tables) </li></ul>
  13. 13. Strategies for storing trees <ul><li>Store a Parent ref. (PK/ID) in each node/leaf </li></ul><ul><ul><li>Classic approach for N-trees (each child knows it‘s parent ) </li></ul></ul><ul><ul><li>„ unlimited“ number of children for each parent </li></ul></ul><ul><li>Store all Child refs (PKs) in each parent node </li></ul><ul><ul><li>Limited number of children (one field for each Child ref.) </li></ul></ul><ul><ul><li>good for binary search trees, B-trees </li></ul></ul><ul><li>Store relations of nodes in a separate table </li></ul><ul><ul><li>Most flexible, but requires JOINs in each SELECT </li></ul></ul><ul><ul><li>allows „heterogeneous“ trees </li></ul></ul><ul><ul><li>separates STRUCTURE from CONTENT (!!!) </li></ul></ul><ul><li>Store „ hints for traversal “ in nodes </li></ul><ul><ul><li>Does not use PKs or IDs at all (!) -> nested sets </li></ul></ul>NODE CHILD PARENT L R
  14. 14. Retrieving Trees from a DB <ul><li>Client-Side recursion </li></ul><ul><ul><li>SELECT parent node </li></ul></ul><ul><ul><ul><li>SELECT its child nodes one by one </li></ul></ul></ul><ul><ul><ul><ul><li>For each child node: SELECT its child nodes one by one… </li></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>For each child node: SELECT its child nodes one by one… </li></ul></ul></ul></ul></ul><ul><li>Server-side recursion </li></ul><ul><ul><li>Recursive Stored Procedures </li></ul></ul><ul><ul><li>Recursive CTEs </li></ul></ul><ul><ul><li>entire tree is returned by a single statement </li></ul></ul><ul><li>„ Neither-side“ recursion: Nested Sets </li></ul>
  15. 15. Pros of Client-Side recursion <ul><li>Client has full control </li></ul><ul><ul><li>What and How is traversed </li></ul></ul><ul><ul><li>When to stop traversal </li></ul></ul><ul><ul><li>Can change the „What and How“ and „When to stop“ anytime during traversal </li></ul></ul><ul><ul><li>like using a debugger in single-step mode </li></ul></ul>
  16. 16. Why we don‘t want client-side rec.: <ul><li>Many Prepares on Server side (calculating plans etc. costs Server time ) </li></ul><ul><li>Many round-trips across the network (each TO-AND-FRO takes time!) </li></ul><ul><li>Can not retrieve tree structures as simple, „flat“ result sets in „one go“ </li></ul><ul><li>( client cares about CONTENT, server about STRUCTURE) </li></ul>a) SLOW b) EXPENSIVE usually
  17. 17. Part 1 <ul><li>Recursive </li></ul><ul><li>Stored </li></ul><ul><li>Procedures </li></ul>
  18. 18. Stored Procedures <ul><li>Can call other Stored Procedures (including themselves ) </li></ul><ul><li>„ Direct“ recursion: a procedure directly calls itself </li></ul><ul><li>„ Indirect“ recursion: procedure A calls procedure B procedure B recursively calls A </li></ul>
  19. 19. Traversing trees with Selectable SPs <ul><li>Recursive Top-Down SP outline: </li></ul><ul><li>SELECT parent node‘s data, SUSPEND </li></ul><ul><li>FOR SELECT <each child node of parent >: </li></ul><ul><ul><li>FOR SELECT from „ self “ SP with the current child as the new parent node, SUSPEND </li></ul></ul>
  20. 20. Recursive SPs: Pros and Cons <ul><li>Pros: </li></ul><ul><ul><li>Recursion on Server side, few round-trips </li></ul></ul><ul><ul><li>PRETTY FAST (pre-compiled to BLR) </li></ul></ul><ul><ul><li>Can handle all sorts of trees in all sorts of ways </li></ul></ul><ul><ul><li>Full access to all PSQL features (!) </li></ul></ul><ul><li>Cons: </li></ul><ul><ul><li>Unflexible (part of the DB‘s metadata ! ) </li></ul></ul><ul><ul><li>Client has little control and no „insight“ ( a SP is like a „black box, set in concrete“ ) </li></ul></ul><ul><ul><li>Can be hard to maintain/change , need GRANTs </li></ul></ul>
  21. 21. Part 2 <ul><li>Nested Sets </li></ul>Take some sets… … and another set… -> „S1“ -> „S2“ … then nest S1 into S2… … then, what do you get?
  22. 22. Nested Sets: Intro same data as Nested Sets : „ classical“ tree: Nested Sets are all about Containment ! … and NO, this slide is NOT about fried eggs!
  23. 23. Nested Sets: different views
  24. 24. Nested Sets: L and R values L R L R L R L R L R
  25. 25. Nested Sets: Rules for L and R <ul><li>L value of ROOT == 1 (ex def.) </li></ul><ul><li>L < R (for all nodes) </li></ul><ul><li>L of each parent node < L of all it‘s children </li></ul><ul><li>R of each parent node > R of all it‘s children </li></ul><ul><li>L == R – 1 for all Leaf nodes if R=L+1: it has no childs! </li></ul><ul><li>Number of Child nodes == ( R – L - 1 ) / 2 </li></ul>
  26. 26. Nested Sets: Storage in DB
  27. 27. INSERT s in Nested Sets
  28. 28. DELETE s in Nested Sets
  29. 29. Moving nodes in Nested Sets
  30. 30. <ul><li>Pros: </li></ul><ul><ul><li>Good for static (read-only), Owner/Containing type trees </li></ul></ul><ul><ul><li>VERY FAST , non-recursive traversal (index on „ L “) </li></ul></ul><ul><ul><li>Can be mixed with „classic“ trees </li></ul></ul><ul><li>Cons: </li></ul><ul><ul><li>UPDATE s/ INSERT s/ DELETE s are VERY „expensive“ </li></ul></ul><ul><ul><li>No direct links between child and parent nodes </li></ul></ul><ul><li>Depends: </li></ul><ul><ul><li>Predefined order of child nodes (Con? Pro?) </li></ul></ul>Nested Sets: Pros and Cons
  31. 31. Part 3 <ul><li>Recursive </li></ul><ul><li>CTEs </li></ul><ul><li>(Common Table Expressions) </li></ul>
  32. 32. Recursive CTEs: Pros and Cons <ul><li>Cons: </li></ul><ul><ul><li>Client must know and understand tree structure </li></ul></ul><ul><ul><li>No full PSQL (just part of a SELECT ) </li></ul></ul><ul><ul><li>No simple way to control the order of traversal (yet) </li></ul></ul>
  33. 33. Recursive CTEs: Pros and Cons <ul><li>Pros: </li></ul><ul><ul><li>Server-side recursion </li></ul></ul><ul><ul><li>fast, few round-trips </li></ul></ul><ul><ul><li>very flexible & dynamic </li></ul></ul><ul><ul><li>transparent to client </li></ul></ul><ul><ul><li>elegant + relatively easy ( once you get it ;-) </li></ul></ul><ul><ul><li>no Metadata changes </li></ul></ul><ul><ul><li>no GRANT…TO PROCEDURE s required </li></ul></ul><ul><ul><li>Can be used in Stored Procedures </li></ul></ul>just about everything else:
  34. 34. „ normal“ CTEs: Intro <ul><li>WITH <alias> AS ( <select_expression> ) --„preamble“ SELECT <…> FROM <alias> -- „main statement“ </li></ul><ul><li>WITH <alias1> AS ( <select_expression1> ), <alias2> AS ( <select_expression2> ) SELECT <…> FROM <alias1> JOIN <alias2> ON <join_condition> </li></ul>multiple CTEs are „chainable“ in one SELECT This is one SELECT you can send from a client „ ad hoc“
  35. 35. Recursive CTEs: Intro <ul><li>a CTE is an „ inline VIEW“ inside a SELECT </li></ul><ul><li>a recursive CTE („view“) can reference itself </li></ul><ul><li>Recursive CTEs can </li></ul><ul><li>recursively traverse tree structures with a </li></ul><ul><li>single „on the fly“ SELECT statement </li></ul><ul><li>from the client very efficiently </li></ul>!
  36. 36. Recursive CTEs: basic structure <ul><li>WITH RECURSIVE <cte_alias> AS ( </li></ul><ul><li>SELECT <parent data> -- root node’s data </li></ul><ul><li> UNION ALL </li></ul><ul><li> SELECT <child data> -- children’s data </li></ul><ul><li>JOIN <cte_alias> ON <parent_link> </li></ul><ul><li>) -- DO // for the Delphians </li></ul><ul><li>SELECT * FROM <cte_alias> </li></ul>
  37. 37. Traversing trees with recursive CTEs <ul><li>WITH RECURSIVE fs_tree AS ( </li></ul><ul><li>SELECT id, filename FROM filesys </li></ul><ul><li>WHERE id_master = 0 -- condition for ROOT node </li></ul><ul><li>UNION ALL </li></ul><ul><li>SELECT ch .id, ch .filename FROM filesys ch -- ch ilds </li></ul><ul><li>JOIN fs_tree pa ON ch .id_master = pa .id ) </li></ul><ul><li>-- ^^^ pa rent_link: p_l ^^^ </li></ul><ul><li>SELECT * FROM fs_tree </li></ul>
  38. 38. Server processing of rec. CTEs I <ul><li>WITH RECURSIVE <x> AS </li></ul><ul><li>( SELECT <parent> -- PA </li></ul><ul><li>UNION ALL </li></ul><ul><li>SELECT <child> -- CH </li></ul><ul><li>JOIN <x> ON P_L ) </li></ul><ul><li>SELECT * FROM <x> </li></ul><ul><li>„ Analyse > Transform > PREPARE“: </li></ul><ul><li>Transform PA (…) </li></ul><ul><li>Transform CH: turn P_L into Params („un-recurse“/„flatten“ child select) </li></ul><ul><li>JOIN <x> ON CH.ID_Parent = PA.ID </li></ul><ul><li>Prepare transformed PA </li></ul><ul><li>Prepare transformed CH </li></ul>What you send: Server Phase I: Preparation WHERE CH.ID_Parent = :ID -- param
  39. 39. Server processing of rec. CTEs II <ul><li>Execute PA („anchor query“) </li></ul><ul><li>For each result row RR : SEND TO CLIENT </li></ul><ul><li>PUSH result set RS to stack </li></ul><ul><ul><li>3.1 Execute CH with current params from RR -> RS2 </li></ul></ul><ul><ul><li>3.2 For each result row RR2 (if any): call 2 . with RR2 as params </li></ul></ul><ul><li>POP RS from stack , goto 2. with next RS row </li></ul>What you get back (Server Phase II: Execution) Recursion, one level down Loop (same level) Back up one level, „unwind“
  40. 40. Recursive results -> „flat“ result set this slide © Vladyslav Khorsun - thanks, Vlad !  A Ch
  41. 41. Ordering Children in recursive CTEs <ul><li>The Problem: </li></ul><ul><ul><li>Because of the UNION , you can‘t have an ORDER BY clause in the CTE‘s „Child“ SELECT </li></ul></ul><ul><ul><li>Since you can not control the order of child traversal, you MUST consider it to be random (!) </li></ul></ul>
  42. 42. Ordering Children in recursive CTEs <ul><li>Solution A (Fb <x>) </li></ul><ul><li>Use DEPTH FIRST BY <columns> clause </li></ul><ul><ul><li>Really ORDERs the Child select in the UNION (just using a different syntax ) </li></ul></ul><ul><ul><li>already returns the tree in the “right” order during traversal , no ordering of result set needed </li></ul></ul>( but : not yet implemented  )
  43. 43. Ordering Children in recursive CTEs <ul><li>„ Solution“ B (Fb 3) : Use a Window Function : with rcte as ( select … from … UNION ALL select …, RANK() OVER(PARTITION BY PARENT_ID ORDER BY <sort col> ) </li></ul><ul><li>Looks clever! Only drawback: it doesn‘t work…(*) and if/when it does, that‘s coincidence ! (*) NOTE: as of build 3.0.0.29631 this WILL actually work in Fb3 – Adriano has just committed a bugfix related to window functions in recursive CTEs. Thanks Adriano! </li></ul>
  44. 44. Ordering Children in recursive CTEs <ul><li>Solution C: </li></ul><ul><li>Use a SELECTABLE SP as Child Select </li></ul><ul><ul><ul><li>Returns the Childs in a defined order (!) </li></ul></ul></ul><ul><ul><ul><li>Unflexible for the client: </li></ul></ul></ul><ul><ul><ul><li>ORDER is pre-defined in the SP… </li></ul></ul></ul><ul><ul><ul><li>Columns are fixed… </li></ul></ul></ul><ul><ul><ul><li>… see all other CON s of Recursive SPs! </li></ul></ul></ul><ul><ul><ul><li>Very clumsy workaround </li></ul></ul></ul>
  45. 45. Ordering Children in recursive CTEs <ul><li>Solution D: </li></ul><ul><li>Construct a sort path </li></ul><ul><ul><ul><li>Works (kind of) ok with Chars (of limited length) </li></ul></ul></ul><ul><ul><ul><li>Works not so well with numerical data </li></ul></ul></ul><ul><ul><ul><li>No index usage </li></ul></ul></ul><ul><ul><ul><li>orders result set (after traversal) </li></ul></ul></ul><ul><ul><ul><li>can take LOTS of reads </li></ul></ul></ul><ul><ul><ul><li>also a clumsy workaround </li></ul></ul></ul><ul><ul><ul><li>But: it works, and it‘s reliable! </li></ul></ul></ul>
  46. 46. Part 4 <ul><li>„ Real world“ </li></ul><ul><li>CTE Examples </li></ul>
  47. 47. „ Fun“ with recursive CTEs <ul><li>Let‘s bake some </li></ul><ul><li>marble cake! </li></ul>Vanilla cake mixture Chocolate cake mixture Chocolate icing
  48. 48. Ingredients (RAW MATerials) <ul><li>Yolk (egg) </li></ul><ul><li>Sugar </li></ul><ul><li>Flour </li></ul><ul><li>Butter </li></ul><ul><li>Milk </li></ul><ul><li>Baking powder </li></ul><ul><li>Chocolate flavour </li></ul><ul><li>Vanilla flavour </li></ul><ul><li>Lemon flavour </li></ul>Flower
  49. 49. Shugga baby! <ul><li>This cake has 5 sub-recipes </li></ul><ul><li>Each has a different % of sugar </li></ul><ul><li>Q1: What % of sugar is in the entire cake ? </li></ul><ul><li>Q2: how much sugar ,… do i need for 5 kg? </li></ul><ul><li>Q3: How much cake can i bake, if i only have <x> [g] of sugar ?? </li></ul>
  50. 50. <ul><li>that‘s about it… </li></ul><ul><li>Thank you for your attention! </li></ul>Questions ? Frank Ingermann [email_address] Want some cake ??? 

×