M
M
Maxim Barulin2016-08-02 12:19:03
SQL
Maxim Barulin, 2016-08-02 12:19:03

[Mssql2012] How to write a recursive expression correctly?

Hello!
There is a table with data, you need to build a recursive query that will select this data like a tree. The problem is that the child element can refer to itself, which leads to infinite recursion.
Example

declare @t table(eNum FLOAT, dNum NVARCHAR(10), tNum FLOAT)
insert into @t values
(1.1,	'1.1.1',1.2),
(1.2,	'1.2.1',2.1),
(1.3,	'1.3.3',(null)),
(1.3,	'1.3.12',(NULL)),
(1.3,	'1.3.11',(null)),
(1.3,	'1.3.15',(null)),
(1.3,	'1.3.8',(null)),
(1.3,	'1.3.2',(null)),
(1.3,	'1.3.13',(null)),
(1.3,	'1.3.14',(null)),
(1.3,	'1.3.7',(null)),
(1.3,	'1.3.9',(null)),
(1.3,	'1.3.5',(null)),
(1.3,	'1.3.6',(null)),
(1.3,	'1.3.10',(null)),
(1.3,	'1.3.1',(null)),
(1.3,	'1.3.4',(null)),
(2.1,	'2.1.4',2.2),
(2.1,	'2.1.3',2.2),
(2.1,	'2.1.1',2.2),
(2.1,	'2.1.6',2.2),
(2.1,	'2.1.2',2.2),
(2.1,	'2.1.7',2.2),
(2.1,	'2.1.5',2.1); --если убрать эту строку, то всё работает

WITH allSteps AS (
  SELECT * FROM @t --тут запрос на получение данных из нескольких таблиц
),
AlgoSteps AS (
  SELECT alst.eNum, alst.dNum, alst.tNum, 1 AS level
    FROM allSteps AS alst 
  WHERE alst.eNum = 1.1

  UNION ALL

  SELECT alst.eNum, alst.dNum, alst.tNum, als.level + 1
    FROM allSteps AS alst 
    INNER JOIN AlgoSteps AS als ON alst.eNum = als.tNum
  WHERE alst.eNum <> 1.1

)
  SELECT * FROM AlgoSteps ORDER BY eNum, dNum
  OPTION (MAXRECURSION 5);

How can I check that an element is already in the selection and ignore it? Tried
WHERE alst.eNum <> 1.1 AND NOT EXISTS (SELECT 1 FROM AlgoSteps s WHERE s.eNum = alst.eNum)

but got an error:
The recursive element of the common table expression "AlgoSteps" has multiple recursive references.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
K
Konstantin Tsvetkov, 2016-08-02
@tsklab

select data like tree
Among other options, I use this trick: I create a temporary table - a list of nodes. I make a cursor out of it. Then I sort through in order, adding for each node child to the end of this table. As a result, we have a complete list.
Clarification:
if you remove this line, then everything works
A "tree" must not have a node reference to itself.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question