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

Откуда:
Сообщений: 11
Имеется базовая таблица A, со структурой:
Id, Name, ParentId

Где Id - идентификатор записи, Name - название записи, ParentId - идентификатор родительской записи. В данной таблице ParentId ссылается на A.Id. Все корневые записи имеют ParentId равный 0.

Есть еще 3 таблицы: B, C, D c такой же структурой данных как и в A (Id, Name, ParentId). В них ParentId так же ссылается на A.Id. В этих таблицах ParentId равным 0 не может быть.

Необходимо: выбрать все записи из А таким образом, что бы под записью из A.ParentId c 0 шли записи из B, C, D в которых ParentId = A.Id. Т.е. отобразить таблицу со всеми связанными записями, что бы дочерние шли за родительскими, а потом за ними шли опять родительские, но уже для других записей и если есть то и для них показывались дочерние и т.д.
19 ноя 09, 21:47    [7953467]     Ответить | Цитировать Сообщить модератору
 Re: Обход таблицы с выборкой из дочерних таблиц  [new]
muk07
Member

Откуда: Челябинск
Сообщений: 1842
если ожидаемая высота дерева, исходящего из записи А не более 32, то
рекурсивная ф-я с курсором внутри решит задачу.
В противном случае ручное ведение стека для организации такой рекурсии.
20 ноя 09, 08:18    [7954237]     Ответить | Цитировать Сообщить модератору
 Re: Обход таблицы с выборкой из дочерних таблиц  [new]
misho misho
Member

Откуда:
Сообщений: 11
muk07, превышать 32 не будет.

Хотелось бы код посмотреть, как это надо реализовывать
20 ноя 09, 08:31    [7954258]     Ответить | Цитировать Сообщить модератору
 Re: Обход таблицы с выборкой из дочерних таблиц  [new]
muk07
Member

Откуда: Челябинск
Сообщений: 1842
create function f(@Parent_ID int)
returns @x table(
id int,
parent_id int,
name sysname
)
begin
--........на написание и отладку этого нужно минут 30. Столько не имею
return
end

обращение
select * from f(null)
20 ноя 09, 08:42    [7954278]     Ответить | Цитировать Сообщить модератору
 Re: Обход таблицы с выборкой из дочерних таблиц  [new]
muk07
Member

Откуда: Челябинск
Сообщений: 1842
Нашёл у себя немного похожее
CREATE FUNCTION [dbo].[CategTovar] (@Root int)  
-- все категории товаров в виде Продукты|Мясные|Колбаса
RETURNS @x table(
	IDD int, -- идентификатор
	CategName varchar(200) COLLATE SQL_Latin1_General_CP1251_CI_AS  -- название
) 
AS  begin
declare @IDD int, @CategName varchar(200), @sql varchar(4000)
if @Root is null begin
	declare ps cursor for
          select Tovar_ID, TovarName 
          from Tovar 
          where IsTovar=0 and Parent_ID is null
          order by TovarName
end else begin
	declare ps cursor for
          select Tovar_ID, TovarName 
          from Tovar 
          where IsTovar=0 and Parent_ID=@Root
          order by TovarName
end
open ps
fetch next from ps into @IDD,@CategName
while @@fetch_status=0 begin
    insert into @x(IDD,CategName) values(@IDD,@CategName)
    insert into @x select IDD,@CategName+' | '+CategName from dbo.CategTovar(@IDD)
    fetch next from ps into @IDD,@CategName
end
close ps
deallocate ps
return
END
20 ноя 09, 08:52    [7954295]     Ответить | Цитировать Сообщить модератору
 Re: Обход таблицы с выборкой из дочерних таблиц  [new]
misho misho
Member

Откуда:
Сообщений: 11
Каким образом не можно передать в

declare ps cursor for
          select Tovar_ID, TovarName 
          from Tovar 
          where IsTovar=0 and Parent_ID is null
          order by TovarName


вместо
from Tovar
название таблицы в виде переменной
from @Table

При попытке сделать так SQL отдает ошибку Must declare the table variable "@Table"
20 ноя 09, 10:57    [7955060]     Ответить | Цитировать Сообщить модератору
 Re: Обход таблицы с выборкой из дочерних таблиц  [new]
muk07
Member

Откуда: Челябинск
Сообщений: 1842
Невозможно указать имя таблицы в переменной.
Только так:
set @sql='select * from ' +@Table
exec (@sql)
20 ноя 09, 12:29    [7955841]     Ответить | Цитировать Сообщить модератору
 Re: Обход таблицы с выборкой из дочерних таблиц  [new]
Anddros
Member

Откуда:
Сообщений: 1077
Для 2005-го и выше:
declare @a table (id int identity, name varchar(10), parent_id int)
declare @b table (id int identity, name varchar(10), parent_id int)
declare @c table (id int identity, name varchar(10), parent_id int)
declare @d table (id int identity, name varchar(10), parent_id int)

insert @a select 'a1',0
union all select 'a2',0
union all select 'a3',1
union all select 'a4',3
union all select 'a5',3

insert @b select 'b1',1
union all select 'b2',1
union all select 'b3',2
union all select 'b4',3
union all select 'b5',3

insert @c select 'c1',5
union all select 'c2',5
union all select 'c3',2
union all select 'c4',2

insert @d select 'd1',4
union all select 'd2',3

;with q as (
select id i,name n, parent_id p, cast(str(id,10) as varchar(8000)) sp 
from @a
where parent_id=0
union all
select id,name,parent_id,cast(sp+str(id,10) as varchar(8000))
from q
inner join @a on i=parent_id)

select i,n,p
from (
select i,n,p,sp,'a't 
from q
union all 
select id,name,parent_id,sp,t
from (select id,name,parent_id,'b't from @b
union all select id,name,parent_id,'c' from @c
union all select id,name,parent_id,'d' from @d)t
inner join q on parent_id=i
)t
order by sp,t
20 ноя 09, 13:15    [7956182]     Ответить | Цитировать Сообщить модератору
 Re: Обход таблицы с выборкой из дочерних таблиц  [new]
misho misho
Member

Откуда:
Сообщений: 11
Всем огромное спасибо! Работает!
20 ноя 09, 13:57    [7956549]     Ответить | Цитировать Сообщить модератору
 Re: Обход таблицы с выборкой из дочерних таблиц  [new]
misho misho
Member

Откуда:
Сообщений: 11
Подскажите, еще, каким образом можно отсортировать значения в итоговой выборке, что бы значения во всех ветках были в алфавитном порядке.
25 ноя 09, 18:52    [7978896]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить