Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 рекурсивный запрос  [new]
a2509
Member

Откуда:
Сообщений: 16
написал простейший рекурсивный запрос. MSDN читал, примеры смотрел.
вместо WHERE e.PARENT_ID = rec.ID inner join писал.
результирующий набор возвращается странным образом.
ожидаемо было, что строка "Row 1.1" будет после "Row 1", в "Row 3.1" после "Row3" и т.п.
на деле все получается иначе.
что не так в запросе?

К сообщению приложен файл. Размер - 32Kb
25 дек 14, 12:45    [17050606]     Ответить | Цитировать Сообщить модератору
 Re: рекурсивный запрос  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8839
a2509,

читайте еще, разбирайте пример из справки. Вы не построили рекурсию.
25 дек 14, 12:50    [17050646]     Ответить | Цитировать Сообщить модератору
 Re: рекурсивный запрос  [new]
Glory
Member

Откуда:
Сообщений: 104751
a2509
что не так в запросе?

Не указана сортировка
сервер за вас не будет додумывать, " что строка "Row 1.1" будет после "Row 1", в "Row 3.1" после "Row3""
25 дек 14, 12:54    [17050678]     Ответить | Цитировать Сообщить модератору
 Re: рекурсивный запрос  [new]
a2509
Member

Откуда:
Сообщений: 16
Владислав Колосов
a2509,
читайте еще, разбирайте пример из справки. Вы не построили рекурсию.


что-то нужно сделать еще для построения рекурсии?
не вижу разницы между запросом из примера

WITH DirectReports(ManagerID, EmployeeID, Title, EmployeeLevel) AS 
(
    SELECT ManagerID, EmployeeID, Title, 0 AS EmployeeLevel
    FROM dbo.MyEmployees 
    WHERE ManagerID IS NULL
    UNION ALL
    SELECT e.ManagerID, e.EmployeeID, e.Title, EmployeeLevel + 1
    FROM dbo.MyEmployees AS e
        INNER JOIN DirectReports AS d
        ON e.ManagerID = d.EmployeeID 
)
SELECT ManagerID, EmployeeID, Title, EmployeeLevel 
FROM DirectReports
ORDER BY ManagerID;


и моим
+
;WITH 
  rec( ID, PARENT_ID, NAME, L) AS (
SELECT 
   ID,
   PARENT_ID,
   NAME,
   0 AS l
 FROM EDMS.TEST2
 WHERE PARENT_ID IS NULL 
 UNION ALL
SELECT 
  e.ID, 
  e.PARENT_ID, 
  e.NAME,
  L+1
FROM EDMS.TEST2 e
  INNER JOIN rec
  ON e.PARENT_ID = rec.ID)
SELECT
  rec.ID,
  rec.PARENT_ID,
  rec.NAME,
  L
FROM rec;


Glory
Не указана сортировка
сервер за вас не будет додумывать, " что строка "Row 1.1" будет после "Row 1", в "Row 3.1" после "Row3""

я вроде бы серверу все объяснил в запросе :)
что еще сортировать и зачем?
есть ID и PARENT_ID, прошу начать с PARETN_ID IS NULL и выстроить иерархию.
25 дек 14, 13:36    [17051002]     Ответить | Цитировать Сообщить модератору
 Re: рекурсивный запрос  [new]
Konst_One
Member

Откуда:
Сообщений: 11625
WITH DirectReports(ManagerID, EmployeeID, Title, EmployeeLevel) AS 
(
    SELECT ManagerID, EmployeeID, Title, 0 AS EmployeeLevel
    FROM dbo.MyEmployees 
    WHERE ManagerID IS NULL
    UNION ALL
    SELECT e.ManagerID, e.EmployeeID, e.Title, EmployeeLevel + 1
    FROM dbo.MyEmployees AS e
        INNER JOIN DirectReports AS d
        ON e.ManagerID = d.EmployeeID 
)
SELECT ManagerID, EmployeeID, Title, EmployeeLevel 
FROM DirectReports
ORDER BY ManagerID;
25 дек 14, 13:37    [17051014]     Ответить | Цитировать Сообщить модератору
 Re: рекурсивный запрос  [new]
a2509
Member

Откуда:
Сообщений: 16
;WITH 
  [color=green]DirectReports[/color]( ID, PARENT_ID, NAME, L) AS (
SELECT 
   ID,
   PARENT_ID,
   NAME,
   0 AS l
 FROM EDMS.TEST2
 WHERE PARENT_ID IS NULL 
 UNION ALL
SELECT 
  e.ID, 
  e.PARENT_ID, 
  e.NAME,
  L+1
FROM EDMS.TEST2 AS e
  INNER JOIN [color=green]DirectReports[/color] AS d
  ON e.PARENT_ID = d.ID)
SELECT
  ID,
  PARENT_ID,
  NAME,
  L
FROM [color=green]DirectReports[/color];


что-то должно поменяться от замены rec на DirectReports?
увы, не поменялось...
25 дек 14, 14:01    [17051190]     Ответить | Цитировать Сообщить модератору
 Re: рекурсивный запрос  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
a2509
что-то должно поменяться от замены rec на DirectReports?
как Вы понимаете слово "рекурсия"?
25 дек 14, 14:04    [17051212]     Ответить | Цитировать Сообщить модератору
 Re: рекурсивный запрос  [new]
o-o
Guest
a2509,

данные покажите, на к-ых не работает.
на простейших ваш первый запрос коррекрно отрабатывает
declare @TEST2 table (id int, PARENT_ID int, NAME int);
insert into @TEST2( ID, PARENT_ID, NAME)
values (1, null, 1), (4, 3, 4), (3, 1, 3), (5, 1, 5)

;WITH 
  rec( ID, PARENT_ID, NAME, L) AS (
SELECT 
   ID,
   PARENT_ID,
   NAME,
   0 AS l
 FROM @TEST2
 WHERE PARENT_ID IS NULL 
 UNION ALL
SELECT 
  e.ID, 
  e.PARENT_ID, 
  e.NAME,
  L+1
FROM @TEST2 e
  INNER JOIN rec
  ON e.PARENT_ID = rec.ID)
SELECT
  rec.ID,
  rec.PARENT_ID,
  rec.NAME,
  L
FROM rec;
---
ID	PARENT_ID	NAME	L
1	NULL	1	0
3	1	3	1
5	1	5	1
4	3	4	2
25 дек 14, 14:33    [17051405]     Ответить | Цитировать Сообщить модератору
 Re: рекурсивный запрос  [new]
a2509
Member

Откуда:
Сообщений: 16
iap
a2509
что-то должно поменяться от замены rec на DirectReports?
как Вы понимаете слово "рекурсия"?


под словом рекурсия я предполагаю, что сервер умеет выбирать данные из таблиц (-ы) и выстраивать их в виде иерархического дерева.
Так, например, делает Oracle.
SELECT 
  t.ID,
  t.PARENT_ID,
  t.NAME
FROM TEST2 t
CONNECT BY PRIOR t.ID = t.PARENT_ID
START WITH t.PARENT_ID IS NULL

и результат как на картинке, т.е. сервер от root всю иерархию выстроил.
заметьте, что цепочка root->Row 3->Row 3.1->Row 3.1.1 выстроена.

в приведенном мной первоначальном и последующих запросах MS SQL подобного результата не получилось.
в результирующем наборе каша.
почему, я не понимаю.

К сообщению приложен файл. Размер - 26Kb
25 дек 14, 14:39    [17051484]     Ответить | Цитировать Сообщить модератору
 Re: рекурсивный запрос  [new]
a2509
Member

Откуда:
Сообщений: 16
запрос с данными
declare @TEST2 table (id UNIQUEIDENTIFIER, PARENT_ID UNIQUEIDENTIFIER, NAME VARCHAR(50));
insert into @TEST2( ID, PARENT_ID, NAME)
values 
('c49ebf97-0ad2-4782-88f9-244986472124', null, 'root'),
('e93296f0-ca96-4400-aef8-adc4b60bf343', 'c49ebf97-0ad2-4782-88f9-244986472124', 'Row 1'),
('1aaad5f5-9318-4758-826a-f68d0ebeb31a', 'c49ebf97-0ad2-4782-88f9-244986472124', 'Row 3'),
('d527d23a-dee1-421f-b37d-f7a6733a7f24', 'c49ebf97-0ad2-4782-88f9-244986472124', 'Row 2'),
('e6f67c26-fcd3-41ab-be55-88983252d749', 'd527d23a-dee1-421f-b37d-f7a6733a7f24', 'Row 2.1'),
('2c28c6a2-5f92-4e04-a01e-ea90583f7305', '1aaad5f5-9318-4758-826a-f68d0ebeb31a', 'Row 3.1'), 
('9e7a4496-51ab-42f7-a0a3-fab203f0da3c', '2c28c6a2-5f92-4e04-a01e-ea90583f7305', 'Row 3.1.1'),
('49f262d1-e678-4d83-bc8c-2b2edbb02f2d', 'e93296f0-ca96-4400-aef8-adc4b60bf343', 'Row 1.1'),
('21065bf8-71df-4047-931e-e95a261fe422', 'e93296f0-ca96-4400-aef8-adc4b60bf343', 'Row 1.2')

;WITH 
  DirectReports( ID, PARENT_ID, NAME, L) AS (
SELECT 
   ID,
   PARENT_ID,
   NAME,
   0 AS l
 FROM EDMS.TEST2
 WHERE PARENT_ID IS NULL 
 UNION ALL
SELECT 
  e.ID, 
  e.PARENT_ID, 
  e.NAME,
  L+1
FROM EDMS.TEST2 AS e
  INNER JOIN DirectReports AS d
  ON e.PARENT_ID = d.ID)
SELECT
  ID,
  PARENT_ID,
  NAME,
  L
FROM DirectReports;
25 дек 14, 14:49    [17051599]     Ответить | Цитировать Сообщить модератору
 Re: рекурсивный запрос  [new]
o-o
Guest
a2509,

фу, ну так надо выражаться правильно.
рекурсия-то получилась, вопрос, в каком виде ответ.
на мою картинку смотрите, иерархии 4 -> 3 -> 1 и 5 -> 1 выстроены.
просто не собраны в одну строку.
а предыдущие ораторы не заметили, что вы ссылаетесь на "якорь",
особенно первый ораклоподобный запрос располагает к тому,
(перечисление таблиц через запятую)
и все вам начали указывать, что вы к якорю не привязываетесь, и про понимание рекурсии спрашивать
25 дек 14, 14:51    [17051623]     Ответить | Цитировать Сообщить модератору
 Re: рекурсивный запрос  [new]
a2509
Member

Откуда:
Сообщений: 16
на всякий случай
Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (X64)
25 дек 14, 14:51    [17051624]     Ответить | Цитировать Сообщить модератору
 Re: рекурсивный запрос  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381
a2509
в приведенном мной первоначальном и последующих запросах MS SQL подобного результата не получилось.
в результирующем наборе каша.
почему, я не понимаю.


так сказали же уже - потому что order by нет. рекурсивное cte само по себе только выборку по иерархии позволяет делать - а какого-то порядка выборки никто не обещал. о порядке вам придется самостоятельно позаботиться. обычно для этого собирают для каждого элемента путь от корня (с фиксированной длиной элементов) и упорядочивают по нему.
25 дек 14, 14:52    [17051635]     Ответить | Цитировать Сообщить модератору
 Re: рекурсивный запрос  [new]
o-o
Guest
a2509,

о блин, да вы и не строку даже собираете, это у вас такие значения с точками, ок,
тогда отгадал Glory: вы просто ответ не сортируете как надо
25 дек 14, 14:54    [17051663]     Ответить | Цитировать Сообщить модератору
 Re: рекурсивный запрос  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1887
declare @TEST2 table (id UNIQUEIDENTIFIER, PARENT_ID UNIQUEIDENTIFIER, NAME VARCHAR(50));
insert into @TEST2( ID, PARENT_ID, NAME)
values 
('c49ebf97-0ad2-4782-88f9-244986472124', null, 'root'),
('e93296f0-ca96-4400-aef8-adc4b60bf343', 'c49ebf97-0ad2-4782-88f9-244986472124', 'Row 1'),
('1aaad5f5-9318-4758-826a-f68d0ebeb31a', 'c49ebf97-0ad2-4782-88f9-244986472124', 'Row 3'),
('d527d23a-dee1-421f-b37d-f7a6733a7f24', 'c49ebf97-0ad2-4782-88f9-244986472124', 'Row 2'),
('e6f67c26-fcd3-41ab-be55-88983252d749', 'd527d23a-dee1-421f-b37d-f7a6733a7f24', 'Row 2.1'),
('2c28c6a2-5f92-4e04-a01e-ea90583f7305', '1aaad5f5-9318-4758-826a-f68d0ebeb31a', 'Row 3.1'), 
('9e7a4496-51ab-42f7-a0a3-fab203f0da3c', '2c28c6a2-5f92-4e04-a01e-ea90583f7305', 'Row 3.1.1'),
('49f262d1-e678-4d83-bc8c-2b2edbb02f2d', 'e93296f0-ca96-4400-aef8-adc4b60bf343', 'Row 1.1'),
('21065bf8-71df-4047-931e-e95a261fe422', 'e93296f0-ca96-4400-aef8-adc4b60bf343', 'Row 1.2')

;WITH 
  DirectReports( ID, PARENT_ID, NAME, L) AS (
SELECT 
   ID,
   PARENT_ID,
   NAME,
   CAST(NAME as varchar(max)) AS l
 FROM @TEST2
 WHERE PARENT_ID IS NULL 
 UNION ALL
SELECT 
  e.ID, 
  e.PARENT_ID, 
  e.NAME,
  L+'/'+CAST(e.NAME as varchar(max))
FROM @TEST2 AS e
  INNER JOIN DirectReports AS d
  ON e.PARENT_ID = d.ID)
SELECT
  ID,
  PARENT_ID,
  NAME,
  L
FROM DirectReports ORDER BY L
25 дек 14, 14:55    [17051667]     Ответить | Цитировать Сообщить модератору
 Re: рекурсивный запрос  [new]
a2509
Member

Откуда:
Сообщений: 16
Спасибо!!!
Получилось то, что хотел. Теперь буду знать.
25 дек 14, 15:08    [17051792]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить