Recursive BAQs
Recursive BAQs
Tim Shoemaker
Principal Consultant, Epicor Software
March 11, 2021
Agenda
Introduction 01
Definitions 02
Illustration 03
Helpful Resources 04
Sample Build 05
Q&A 06
2
Introduction
Who Am I?
3
Introduction
Focus:
• ERP Manufacturing Operations
• Engineering, MRP, Production, Inventory, Purchasing, Sales, etc
• Technology
• Product Configurator, BPMs, Queries, Dashboards, Data Migrations
4
Definitions
5
Definition
6
Definition
CTE Query:
• Common Table Expressions query
• Creates a temporary table
• Can be used as a sub-query (similar to an inner-sub query)
• Only type of sub-query that can be recursive by using a UnionAll query
• UnionAll query:
• A sub-query that unions all values from previous queries
• All columns MUST return identical value types
• Must have a TOP query that uses it
7
Illustrations
(& Screenshots)
8
Recursive Illustrated
Material 1
Assy 2
Material 2
Assy 1
Assy3 Material 3
9
Recursive Illustrated CTE
Query
Source:
https://medium.com/swlh/rec
ursion-in-sql-explained-
graphically-679f6a0f143b
UnionALL
Query
TOP
Query
10
Recursive Screenshots
11
Recursive Screenshots
12
Recursive Screenshots – The SQL we will build
with [ctequery] as (
select
[anchor].[MenuID] as [anchor_MenuID],
[anchor].[MenuDesc] as [anchor_MenuDesc],
(cast (anchor.MenuID as nvarchar(500))) as [Calculated_SortOrder],
(0) as [Calculated_level]
from
Ice.Menu as anchor
where
(anchor.ParentMenuID = '')
union all
select
[childMenus].[MenuID] as [childMenus_MenuID],
[childMenus].[MenuDesc] as [childMenus_MenuDesc],
(cast (ctequery.Calculated_SortOrder + ', ' + right('0000' + cast(childMenus.Sequence as varchar(4)),4) as nvarchar(500))) as [Calculated_SortOrder],
(ctequery.Calculated_level + 1) as [Calculated_level]
from
ctequery as ctequery
inner join Ice.Menu as childMenus on childMenus.ParentMenuID = ctequery.anchor_MenuID)
select
[ctequery1].[anchor_MenuID] as [anchor_MenuID],
[ctequery1].[anchor_MenuDesc] as [anchor_MenuDesc],
[ctequery1].[Calculated_SortOrder] as [Calculated_SortOrder],
[ctequery1].[Calculated_level] as [Calculated_level],
(replicate(' ', ctequery1.Calculated_level) + '+ ' + ctequery1.anchor_MenuDesc) as [Calculated_Indented]
from
ctequery as ctequery1
order by
ctequery1.Calculated_SortOrder
13
Resources
14
Helpful Webpage Links found
Recursive: https://medium.com/swlh/recursion-in-sql-explained-graphically-679f6a0f143b
15
Sample Build
Wrong
16
Step 1
Test
Turn into CTE Query
17
Step 2 – Query 2
Test
Turn into UNIONALL Query
18
Step 3 – Query 3
Test
Specify SORT order in query & test again
19
DEMO
20
Recursive Screenshots – The SQL we will build
with [ctequery] as (
select
[anchor].[MenuID] as [anchor_MenuID],
[anchor].[MenuDesc] as [anchor_MenuDesc],
(cast (anchor.MenuID as nvarchar(500))) as [Calculated_SortOrder],
(0) as [Calculated_level]
from
Ice.Menu as anchor
where
(anchor.ParentMenuID = '')
union all
select
[childMenus].[MenuID] as [childMenus_MenuID],
[childMenus].[MenuDesc] as [childMenus_MenuDesc],
(cast (ctequery.Calculated_SortOrder + ', ' + right('0000' + cast(childMenus.Sequence as varchar(4)),4) as nvarchar(500))) as [Calculated_SortOrder],
(ctequery.Calculated_level + 1) as [Calculated_level]
from
ctequery as ctequery
inner join Ice.Menu as childMenus on childMenus.ParentMenuID = ctequery.anchor_MenuID)
select
[ctequery1].[anchor_MenuID] as [anchor_MenuID],
[ctequery1].[anchor_MenuDesc] as [anchor_MenuDesc],
[ctequery1].[Calculated_SortOrder] as [Calculated_SortOrder],
[ctequery1].[Calculated_level] as [Calculated_level],
(replicate(' ', ctequery1.Calculated_level) + '+ ' + ctequery1.anchor_MenuDesc) as [Calculated_Indented]
from
ctequery as ctequery1
order by
ctequery1.Calculated_SortOrder
21
Questions?
22
Thank you
Tim Shoemaker
Principal Consultant
[email protected]
+1.949.294.0203
23