From SQL to SPL: Total under recursive relationship

A certain database has a ticket table and a work hour table. The ticket table stores the relationship between each ticket and its parent ticket, forming a self-association structure:

ticketid

parentID

1

6

2

7

3

8

4

9

5

10

6

18

7

19

8

20

9

21

10

22

11

23

12

18

13

19

14

20

15

21

16

22

17

23

18

24

19

25

20

26

21

27

22

28

23

29

24

30

25

30

26

30

27

30

28

30

29

30

30

0

The work hour table stores multiple working hours corresponding to each ticket:

ticketid

hours

0

4

1

2

1

1

2

5

2

1

3

5

3

2

3

2

4

1

4

4

4

1

4

5

5

3

5

2

6

3

6

3

6

2

6

1

6

1

7

1

7

2

7

4

7

2

8

5

8

2

8

4

9

5

9

2

10

5

10

4

10

4

11

1

11

1

12

3

12

2

12

5

13

2

13

2

14

5

14

1

14

2

14

1

15

5

15

5

15

1

15

3

16

2

16

1

16

5

17

4

17

4

18

1

18

5

18

1

19

1

19

1

19

4

19

3

20

2

20

2

20

5

21

3

21

5

22

3

22

4

22

5

23

3

23

2

23

5

23

4

24

4

24

4

24

1

24

4

25

2

25

4

25

3

26

2

26

2

26

4

26

2

26

2

27

2

27

3

28

5

28

1

28

3

28

1

29

1

29

4

30

0

30

0

Now we need to calculate the working hours for each ticket and recursively calculate the sum of the working hours for that ticket and all subordinate tickets, which is the total working hours.

MainID

Direct_hours

Total_hours

1

3

3

2

6

6

3

9

9

4

11

11

5

5

5

6

10

13

7

9

15

8

11

20

9

7

18

10

13

18

11

2

2

12

10

10

13

4

4

14

9

9

15

14

14

16

8

8

17

8

8

18

7

30

19

9

28

20

9

38

21

8

40

22

12

38

23

14

24

24

13

43

25

9

37

26

12

50

27

5

45

28

10

48

29

5

29

30

0

252

SQL

WITH    CTE_TREE AS (
        SELECT  parentid AS parentid, ticketid AS children
        FROM    tickets t
        WHERE   parentID <> 0
        UNION
        SELECT  parentid, NULL
        FROM    tickets
        WHERE   parentID <> 0
        UNION
        SELECT  ticketid, NULL
        FROM    tickets
    )
    ,   CTE_TRAVERSE AS (
        SELECT  parentid AS mainId, children AS nextParent
        FROM    CTE_TREE
        UNION ALL
        SELECT  t.mainId, tree.children
        FROM    CTE_TREE tree
        INNER JOIN CTE_TRAVERSE t
            ON  t.nextParent = tree.parentid
        WHERE   tree.children <> ''
    )
    SELECT  t.MainID
    ,   SUM(CASE WHEN t.nextparent IS NULL THEN h.Hours END) AS Direct_hours
    ,   SUM(h.Hours) AS Total_hours
    FROM    CTE_TRAVERSE t
    INNER JOIN Hours h
        ON  h.ticketid = t.nextparent
        OR  (h.ticketid = t.mainID AND t.nextparent IS NULL)
    GROUP BY t.mainId

SQL requires multiple subqueries to implement self-association and recursive relationships, and the code is complex and difficult to understand. SPL directly provides reference functions to establish self-associations and recursive functions to take all subordinate nodes:

https://try.esproc.com/splx?2SJ


 A

1

$select t.ticketid ticketid,t.parentID parentID,h.hours hours from tickets.txt t left join (select ticketid,sum(hours) hours from hours.txt group by ticketid) h on t.ticketid=h.ticketid

2

>A1.switch(parentID,A1:ticketid)

3

=A1.new(ticketid:MainID,hours:Direct_hours,hours+A1.nodes(parentID,~).sum(hours):Total_hours)

A1 Load data and calculate the direct working hours for each ticket based on the ticket table.

A2 Set the parent ticket field of each record to point to the parent ticket record and establish a self-association relationship. The switch function can modify field values to records.

A3 Create a new two dimensional table, where the total working hours of the current ticket are equal to the direct working hours of the current ticket plus the sum of the working hours of all its subordinate sub tickets. The function nodes can recursively calculate all the subordinate records of a certain record.

Question sourcehttps://stackoverflow.com/questions/78089375/how-to-add-total-hours-for-a-ticket-including-all-child-tickets