Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Запрос с внутренним циклом  [new]
sql-щик
Guest
Здравствуйте уважаемые мастера! Такая проблема, есть таблица (древовидное меню):
id,pid,name
1,0,Начало
2,1,Продукты
3,1,Промтовары
4,2,Молочные
5,2,Хлеб
.....
Нужно выбрать в запросе все ветки, т.е.
Начало
Начало-Продукты
Начало-Промтовары
Начало-Продукты-Молочные
Начало-Продукты-Хлеб

В виде таблицы, т.е. не PRINT в курсоре, а обычной таблицы, возможно ли это сделать?
4 авг 05, 13:09    [1763364]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с внутренним циклом  [new]
Misha 'Karn' Ivanov
Member

Откуда:
Сообщений: 79
случай общий? или глубина дерева известна?
4 авг 05, 13:12    [1763379]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с внутренним циклом  [new]
sql-щик
Guest
Глубина не более 10 узлов, а можно в обратном порядке, т.е. идем от точки, делаем запрос в цикле
IF EXIST(SELECT * FROM table WHERE pid=X),
если записей нет, то BREAK. Если есть, то суммируем строку с пред. найденой.
Идея есть, только не знаю как реализовать :( Хотя может есть и более простые ходы (всей мощи SQL тоже не представляю).
4 авг 05, 13:21    [1763430]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с внутренним циклом  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
SQL как раз с деревьями очень плохо работает. Но, если вы наберете в поиске слово дерево или деревья, найдете много чего полезного для себя.
4 авг 05, 13:26    [1763447]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с внутренним циклом  [new]
Misha 'Karn' Ivanov
Member

Откуда:
Сообщений: 79
ну если вас не пугают 10 джойнов - то все просто :)
4 авг 05, 13:27    [1763450]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с внутренним циклом  [new]
sql-щик
Guest
Ага, спасибо, вроде нашел.
4 авг 05, 13:41    [1763518]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с внутренним циклом  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1873
declare @Products table(id int,pid int,name varchar(20))
insert into @Products values(1,0,'Начало')
insert into @Products values(2,1,'Продукты')
insert into @Products values(3,1,'Промтовары')
insert into @Products values(4,2,'Молочные')
insert into @Products values(5,2,'Хлеб')
insert into @Products values(6,4,'Кефир')
insert into @Products values(7,4,'Молоко')
/*
.....
Нужно выбрать в запросе все ветки, т.е. 
Начало
Начало-Продукты
Начало-Промтовары
Начало-Продукты-Молочные
Начало-Продукты-Хлеб
*/


select 
isnull(p0.name,'')+'-'+
isnull(p1.name,'')+'-'+
isnull(p2.name,'')+'-'+
isnull(p3.name,'')+'-'+
isnull(p4.name,'')+'-'+
isnull(p5.name,'') as Path
from @Products p0
left outer join @Products p1 on (p1.pid=p0.id)
left outer join @Products p2 on (p2.pid=p1.id)
left outer join @Products p3 on (p3.pid=p2.id)
left outer join @Products p4 on (p4.pid=p3.id)
left outer join @Products p5 on (p5.pid=p4.id)
where not exists(select top 1 1 from @Products where id = p0.pid)

4 авг 05, 13:48    [1763557]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с внутренним циклом  [new]
sql-щик
Guest
LexusR
Спасибо!
4 авг 05, 14:00    [1763627]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с внутренним циклом  [new]
sql-щик
Guest
Начало Продукты Молочные Кефир
Начало Продукты Молочные Молоко
Начало Продукты Хлеб
Начало Промтовары

Обрал черточки, а то их всегда 5 пишется в товаре, и ещё вопрос, тут выбралось 4 строки из всех, т.е. это только последние строки выбираеются, т.е. крайние, у который больше нет детей.. понятно впринципе.. Может так и лучше.
4 авг 05, 14:05    [1763662]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с внутренним циклом  [new]
mmms_
Guest
Продолжу тему, а как можно вытащить ID, вместе с названиями, в Коде от LexusR, сейчас возвр. одно значение.
4 авг 05, 21:09    [1765419]     Ответить | Цитировать Сообщить модератору
 Re: Запрос с внутренним циклом  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1873
mmms_
Продолжу тему, а как можно вытащить ID, вместе с названиями, в Коде от LexusR, сейчас возвр. одно значение.

select 
cast(p0.id as varchar(10))
+case when p1.id is not null then '/'+cast(p1.id as varchar(10)) else '' end 
+case when p2.id is not null then '/'+cast(p2.id as varchar(10)) else '' end 
+case when p3.id is not null then '/'+cast(p3.id as varchar(10)) else '' end 
+case when p4.id is not null then '/'+cast(p4.id as varchar(10)) else '' end 
+case when p5.id is not null then '/'+cast(p5.id as varchar(10)) else '' end 
as All_ID,
isnull(p0.name,'')
+case when p1.id is not null then '/'+p1.name else '' end 
+case when p2.id is not null then '/'+p2.name else '' end 
+case when p3.id is not null then '/'+p3.name else '' end 
+case when p4.id is not null then '/'+p4.name else '' end 
+case when p5.id is not null then '/'+p5.name else '' end 
as Path
from @Products p0
left outer join @Products p1 on (p1.pid=p0.id)
left outer join @Products p2 on (p2.pid=p1.id)
left outer join @Products p3 on (p3.pid=p2.id)
left outer join @Products p4 on (p4.pid=p3.id)
left outer join @Products p5 on (p5.pid=p4.id)
where not exists(select top 1 1 from @Products where id = p0.pid)
5 авг 05, 06:03    [1765700]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить