Download as pdf or txt
Download as pdf or txt
You are on page 1of 23

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

Tim Shoemaker - Principal Consultant

Epicor Employee since Aug 1999


• Technical Support first 5 years
• Professional Services team since Dec 2004
• Prior to Epicor – an Epicor Avanté Customer
• Presented at Epicor Insights at least 12 years, attended as user 1 year
• Present at numerous User Group meetings

Focus:
• ERP Manufacturing Operations
• Engineering, MRP, Production, Inventory, Purchasing, Sales, etc
• Technology
• Product Configurator, BPMs, Queries, Dashboards, Data Migrations

4
Definitions

What are we talking about

5
Definition

Recursive Query: (Found on the web – Sherlock would be proud):


• Recursive queries are used to query hierarchical data

More Important to today:


• Recursive Queries are those that are Multi-Level queries using the same
data tables.

• Examples of where you need a Recursive Query:


• Bill Of Material
• Job Structure
• Employee structure (Manager, Supervisor, Lead, Shop Floor worker)
• Menu Structure

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)

A Picture is worth a thousand words

8
Recursive Illustrated

Level 0 Level 1 Level 2


(CTE) (UnionAll) (UnionAll)

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

Helpful Webpages Found:

14
Helpful Webpage Links found

CTE Query in LINQ: https://linq2db.github.io/articles/sql/CTE.html

SQL CTE: https://www.tutorialgateway.org/sql-server-cte/

Recursive: https://medium.com/swlh/recursion-in-sql-explained-graphically-679f6a0f143b

15
Sample Build

Finally, the PowerPoint ends, and we get to see


this in action! Right?

Wrong
16
Step 1

Create ANCHOR TOP query:


• MENU Table
• Fields:
• MenuID
• MenuDesc
• Sequence
• SortOrder (Calculated = cast(menuID as nvarchar(500)
• Level (calculated) = 0

Test
Turn into CTE Query

17
Step 2 – Query 2

Create UNIONALL query (as a TOP)


• MENU Table
• Link to CTE Anchor query
• Fields:
• MenuID
• MenuDesc
• Sequence
• SortOrder (Calculated =
• cast(AnchorSortOrder + ‘, ‘
+ right(‘0000’
+ cast (child sequence as nvarchar(4)),4) as nvarchar(500))
• Level (calculated) = Anchor.Level + 1

Test
Turn into UNIONALL Query

18
Step 3 – Query 3

Create TOP query (as a TOP)


• CTE Anchor query
• Fields: (include ALL fields)

Test
Specify SORT order in query & test again

Add Indented Display


Remove unnecessary fields

OPTIONAL: Add additional tables.

19
DEMO

(Tim, it is time to go to the live 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?

Your Turn to talk

22
Thank you
Tim Shoemaker
Principal Consultant

[email protected]
+1.949.294.0203

23

You might also like