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

Откуда:
Сообщений: 34
Здравствуйте!
Есть таблица дерева вида

create table(
id int not null
, partner_id int not null
,my_partner int null
,all_partner int null
, Primary key(id ,partner_id)
)
Так вот изначально предполагалось в поле my_partner - хранить количество непосредственных потомков
а в поле all_partner - количество всех потомков в дереве.

Есть процедура вида (написанна приблизительно без условий цыкла)
CREATE PROCEDURE [dbo].[update_tree]
@user_id int
AS
BEGIN
declare @current_member int
set @current_member = @user_id
update table set
my_partner = (select count(1) from table where id = @current_member)
,all_partner= (select isnull(my_partner ,0)+(select ISNULL(SUM(all_partner),0) from table where id=@current_member )
from table where partner_id = @current_member)

Всё работает вроде как неплохо пока не встречается зацыкленость, то есть для определённого id - его потомок может стоять над ним.
В общем если кто сталкивался с таким прошу совета, возможно есть уже готовые решения таких случаев, для такой структуры таблицы
22 авг 12, 11:14    [13047736]     Ответить | Цитировать Сообщить модератору
 Re: Подсчёт зацыкленого дерева  [new]
rector
Member

Откуда: Киев
Сообщений: 57
Nelly_lucky,

А какой смысл хранить количество непосредственно в строках и каждый раз делать update и пересчет по всей таблице в цикле?

Если версия сервера >= 2005 используйте [url=cte ]http://msdn.microsoft.com/ru-ru/library/ms186243%28v=sql.90%29.aspx[/url]
для рекурсии
22 авг 12, 11:26    [13047819]     Ответить | Цитировать Сообщить модератору
 Re: Подсчёт зацыкленого дерева  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Может тогда лучше HierarchyID?
22 авг 12, 17:13    [13050847]     Ответить | Цитировать Сообщить модератору
 Re: Подсчёт зацыкленого дерева  [new]
циклы
Guest
Mnior
Может тогда лучше HierarchyID?

Там циклов не получиться, а у них они почему-то есть
22 авг 12, 17:20    [13050894]     Ответить | Цитировать Сообщить модератору
 Re: Подсчёт зацыкленого дерева  [new]
делатель update-ов
Guest
rector
Nelly_lucky,

А какой смысл хранить количество непосредственно в строках и каждый раз делать update и пересчет по всей таблице в цикле?

Если версия сервера >= 2005 используйте [url=cte ]http://msdn.microsoft.com/ru-ru/library/ms186243%28v=sql.90%29.aspx[/url]
для рекурсии

это зависит от частоты чтений и изменений.
если дерево почти не меняется, но часто и много читается, то смысл есть.
22 авг 12, 17:22    [13050905]     Ответить | Цитировать Сообщить модератору
 Re: Подсчёт зацыкленого дерева  [new]
зацыкленное дерево
Guest
вопрос к автору, если у вас есть зацыкленности то вообще не что писать в поле all_partner в простейшем примере


id, patern_id
1,  2
2,  1
22 авг 12, 17:26    [13050930]     Ответить | Цитировать Сообщить модератору
 Re: Подсчёт зацыкленого дерева  [new]
зацыкленное дерево
Guest
fix
зацыкленное дерево
вопрос к автору, если у вас есть зацыкленности то вообще не ПОНЯТНО что писать в поле all_partner в простейшем примере


id, patern_id
1,  2
2,  1
22 авг 12, 17:28    [13050942]     Ответить | Цитировать Сообщить модератору
 Re: Подсчёт зацыкленого дерева  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
циклы
Mnior
Может тогда лучше HierarchyID?

Там циклов не получиться, а у них они почему-то есть
Ну дык и к тому и веду.
Как я понял ТС нужно их предотвратить.
23 авг 12, 00:10    [13052534]     Ответить | Цитировать Сообщить модератору
 Re: Подсчёт зацыкленого дерева  [new]
Nelly_lucky
Member

Откуда:
Сообщений: 34
зацыкленное дерево
fix
зацыкленное дерево
вопрос к автору, если у вас есть зацыкленности то вообще не ПОНЯТНО что писать в поле all_partner в простейшем примере


id, patern_id
1,  2
2,  1


В таком случае писать 1
28 авг 12, 14:47    [13076380]     Ответить | Цитировать Сообщить модератору
 Re: Подсчёт зацыкленого дерева  [new]
qwerty112
Guest
Nelly_lucky,

если в дерееве есть циклы - это не дерево
28 авг 12, 14:57    [13076486]     Ответить | Цитировать Сообщить модератору
 Re: Подсчёт зацыкленого дерева  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Какие же вы лентяи.
CREATE TRIGGER [trTableTreeCheck] ON [dbo].[Table]
AFTER INSERT,UPDATE AS BEGIN
	SET NOCOUNT NO;

	IF Update(ID)
	OR Update(Parent) BEGIN
		DECLARE	@List	VarChar(max)
		;WITH Tree (Parent,Child) AS (
			SELECT	Parent, ID
			FROM	Inserted
		UNION ALL
			SELECT	 P.Parent
				,C.Child
			FROM	     Tree		C
				JOIN dbo.[Table]	P ON P.ID = C.Parent
			WHERE	C.Parent != C.Child
		)	SELECT	@List	= Stuff((
				SELECT	 ',{',I.ID AS [*],',',I.Parent AS [*],'}'	-- ,Code AS [*],Name AS [*]
				FROM	     Tree	T
					JOIN Inserted	I ON I.ID = T.Child
				WHERE	T.Parent = T.Child
				FOR XML Path(''),Type).value('text()[1]','VarChar(max)'),1,1,' ')
		IF (@List IS NOT NULL) BEGIN
			ROLLBACK
			RAISERROR('Найдена зацикленность в дереве:%s',18,1,@List)
			RETURN
		END
	END
END
GO
28 авг 12, 15:58    [13077136]     Ответить | Цитировать Сообщить модератору
 Re: Подсчёт зацыкленого дерева  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Mnior
SET NOCOUNT ON;
28 авг 12, 16:00    [13077152]     Ответить | Цитировать Сообщить модератору
 Re: Подсчёт зацыкленого дерева  [new]
trew
Member

Откуда: Москва
Сообщений: 2646
Nelly_lucky,

Проектирование баз данных: иерархические структуры. Деревья в SQL
Выберите удобный Вам вариант, если есть возможность по-другому спроектировать таблицу.
28 авг 12, 20:37    [13078681]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить