Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
Author |
Topic |
afroz
Starting Member
6 Posts |
Posted - 2010-09-14 : 08:36:45
|
Hi!I'm using sql server 2000, I need to count number of nodes in left and right side of a root node....suppose i've entries in table asnode parent_node Position node_name1 0 'L' abc2 1 'L' b13 1 'R' b24 2 'L' c15 2 'R' c26 3 'L' d1if i supplied node '1' then it should Give result asleft count=3 andright count =2actually what i want is this..For my entries tree will be like this.. 1(abc) / / (b1) 2 3(b2) /\ / / \ / (c1)4 5(c2)6(d1)Now if i give i/p as 1 theneft count=3 (b1,c1,c2) andright count =2 (b2,d1)if the tree is like this... 1(abc) / | / | (b1) 2 | 3(b2) /\ | / / \ | / (c1)4 5(c2)| 6(d1) | / \ | / | (d2)7 8(e1)the middle line is just imaginary to differentiate left and right nodes for node '1(abc)'Now if i give i/p as 1 thenleft count=3 (b1,c1,c2) andright count =4(b2,d1,d2,e1) I DONT WANT TO USE CURSORS BECAUSE I'VE SOLUTION WITH CURSOR BUT THERE ARE THOUSANDS OF RECORDS IN THE TABLE ,SO EXECUTION TIME OF PROCEDURE IS V VERY HIGH SOMETIMES IT STRUCK SO PLEASE SUGGEST ME SOMETHING......Please....Please help me out i'm strucked from many days...Thanx in advance..afrozz.. |
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2010-09-14 : 10:09:54
|
can you upgrade to 2005? If you could then this would be a pretty easy recursive CTE.Here's a method involving a recursive while loop that *should* work on sql 2000/*node parent_node Position node_name1 0 'L' abc2 1 'L' b13 1 'R' b24 2 'L' c15 2 'R' c26 3 'L' d1if i supplied node '1' then it should Give result asleft count=3 andright count =2*/DECLARE @foo TABLE ( [node] INT , [parent_node] INT , [position] CHAR(1) , [node_name] VARCHAR(255) )INSERT @foo ([node], [parent_node], [position], [node_name]) SELECT 1, 0, 'L', 'abc'UNION SELECT 2, 1, 'L', 'b1'UNION SELECT 3, 1, 'R', 'b2'UNION SELECT 4, 2, 'L', 'c1'UNION SELECT 5, 2, 'R', 'c2'UNION SELECT 6, 3, 'L', 'd1'DECLARE @targetNodeID INT SET @targetNodeID = 1DECLARE @level INT SET @level = 1DECLARE @rows INT SET @rows = 0DECLARE @recursiveMap TABLE ( [nodeID] INT , [level] INT , [position] CHAR(1) )INSERT @recursiveMap ([nodeID], [level], [position])SELECT [node], 0, [position]FROM @fooWHERE [parent_node] = @targetNodeIDSET @rows = @@ROWCOUNTWHILE ( @rows > 0 ) BEGIN INSERT @recursiveMap ([nodeID], [level], [position]) SELECT f.[node] , @level , f.[position] FROM @foo AS f JOIN @recursiveMap AS rm ON rm.[nodeID] = f.[parent_node] WHERE rm.[level] = @level - 1 SET @rows = @@ROWCOUNT SET @level = @level + 1END-- Raw dump of recusivemapSELECT @targetNodeID AS [target Node Id] , SUM(CASE WHEN [position] = 'L' THEN 1 ELSE 0 END) AS [Left Count] , SUM(CASE WHEN [position] = 'R' THEN 1 ELSE 0 END) AS [Right Count]FROM @recursiveMap Charlie===============================================================Msg 3903, Level 16, State 1, Line 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2010-09-14 : 10:10:54
|
of course -- with the real tables you'd be able to make / use indexes as appropriate for the recursive while loopshould be a lot quicker than a cursor!Charlie===============================================================Msg 3903, Level 16, State 1, Line 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
|
|
afroz
Starting Member
6 Posts |
Posted - 2010-09-15 : 08:25:32
|
Thanx Charlie,thank u very much for your valuable reply.. The above code just counts no of nodes which are left and right to parent But my actual problem is this..node parent_node Position node_name1 0 'L' abc2 1 'L' b13 1 'R' b24 2 'L' c15 2 'R' c26 3 'L' d1if i supplied node '1' then it should Give result asleft count=3 andright count =2actually what i want is this..For my entries tree will be like this.. 1(abc) / | / | (b1)2 | 3(b2) / \ | / (c1)4(c2)5 | 6(d1)Now if i give i/p as 1 theneft count=3 (b1,c1,c2) andright count =2 (b2,d1)if the tree is like this... 1(abc) / | / | (b1)2 | 3(b2) / \ | / / \ | / (c1)4 5(c2)| 6(d1) | / | / (d2)7 8(e1) the middle line is just imaginary to differentiate left and right nodes for node '1(abc)'table entries for above tree is like this node parent_node Position node_name 1 0 'L' abc 2 1 'L' b1 3 1 'R' b2 4 2 'L' c1 5 2 'R' c2 6 3 'L' d1 7 6 'L' d2 8 6 'R' d2Now if i give i/p as 1 thenleft count=3 (b1,c1,c2) andright count =4(b2,d1,d2,e1) plz help me out...awaiting for your valuable reply...afrozz.. |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2010-09-15 : 09:23:17
|
You could try this, its a bit of a hack though.DECLARE @foo TABLE ( [node] INT , [parent_node] INT , [position] CHAR(1) , [node_name] VARCHAR(255) )INSERT @foo ([node], [parent_node], [position], [node_name]) SELECT 1, 0, 'L', 'abc'UNION SELECT 2, 1, 'L', 'b1'UNION SELECT 3, 1, 'R', 'b2'UNION SELECT 4, 2, 'L', 'c1'UNION SELECT 5, 2, 'R', 'c2'UNION SELECT 6, 3, 'L', 'd1'DECLARE @targetNodeID INT SET @targetNodeID = 1DECLARE @level INT SET @level = 1DECLARE @rows INT SET @rows = 0DECLARE @recursiveMap TABLE ( [nodeID] INT , [level] INT , [position] CHAR(1) , [node_name] VARCHAR(255) )INSERT @recursiveMap ([nodeID], [level], [position], [node_name])SELECT [node], 0, [position], [node_name]FROM @fooWHERE [parent_node] = @targetNodeIDSET @rows = @@ROWCOUNTWHILE ( @rows > 0 ) BEGIN INSERT @recursiveMap ([nodeID], [level], [position], [node_name]) SELECT f.[node] , @level , f.[position] , f.[node_name] FROM @foo AS f JOIN @recursiveMap AS rm ON rm.[nodeID] = f.[parent_node] WHERE rm.[level] = @level - 1 SET @rows = @@ROWCOUNT SET @level = @level + 1ENDDECLARE @leftCount INT SET @leftCount = 0DECLARE @rightCount INT SET @rightCount = 0DECLARE @leftNodes VARCHAR(8000) SET @leftNodes = ''DECLARE @rightNodes VARCHAR(8000) SET @rightNodes = ''SELECT @leftCount = @leftCount + CASE [position] WHEN 'L' THEN 1 ELSE 0 END , @rightCount = @rightCount + CASE [position] WHEN 'R' THEN 1 ELSE 0 END , @leftNodes = @leftNodes + CASE [position] WHEN 'L' THEN CASE WHEN @leftNodes = '' THEN '' ELSE ', ' END + [node_name] ELSE '' END , @rightNodes = @rightNodes + CASE [position] WHEN 'R' THEN CASE WHEN @rightNodes = '' THEN '' ELSE ', ' END + [node_name] ELSE '' ENDFROM @recursiveMapSELECT @leftCount AS [Left Count] , @rightCount AS [Right count] , @leftNodes AS [Left Nodes] , @rightNodes AS [Right Nodes] The leftNodes and RightNodes variables will probably depend on CLUSTERED INDEX settings in the recursiveMap table you implement.As I said -- this is a hack. Can you upgrade to 2005?Charlie===============================================================Msg 3903, Level 16, State 1, Line 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
|
|
afroz
Starting Member
6 Posts |
Posted - 2010-09-16 : 05:54:36
|
Hi Charlie!Its just counting the no of nodes which are left positioned and right positioned in tree ,But my requirement quite different..As i mentioned in the above tree(Second tree with 8 nodes), the table entries are like this node parent_node Position node_name1 0 'L' abc2 1 'L' b13 1 'R' b24 2 'L' c15 2 'R' c26 3 'L' d17 6 'L' d28 6 'R' e1Now if i give i/p as 1 thenleft count=3 (b1,c1,c2) andright count =4(b2,d1,d2,e1) But the above query producing the output asleft count=4 (b1, c1, d1, d2) andright count =3(b2, c2, E1)This counting based on node position towards parent eg.(b1, c1, d1, d2) are all left positioned in tree and (b2, c2, E1) are all right positioned in treei need the left and right counts without node names in paranthesis..Please note node b1,c1,c2 are in left to parent 'abc' and node b2,d1,d2,e1 are in right to 'abc'...PLEASE PUT A TREE STRUCTURE TO BETTER UNDERSTAND MY PROBLEM, PLEASE CHARLIE.. awaiting for your help.. Thanx in advance..afrozz.. |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2010-09-16 : 06:26:07
|
AH -- I understand now. You want a count of any record left and right of the orrignal root node!Here. I've rewritten using temp tables so to add an index./*node parent_node Position node_name1 0 'L' abc2 1 'L' b13 1 'R' b24 2 'L' c15 2 'R' c26 3 'L' d17 6 'L' d28 6 'R' e1MAP ---------1--------- | | 2 3 / \ / / \ / 4 5 6 / 7 8*/IF OBJECT_ID('tempDb..#nodeMap') IS NOT NULL DROP TABLE #nodeMapCREATE TABLE #nodeMap ( [node] INT PRIMARY KEY CLUSTERED , [parent_node] INT , [Position] CHAR(1) , [node_name] VARCHAR(50) )CREATE INDEX RECURS_IX_NODEMAP_PARENT_NODE ON #nodeMap ([parent_node])INSERT #nodeMap SELECT 1, 0, 'L', 'abc'UNION SELECT 2, 1, 'L', 'b1'UNION SELECT 3, 1, 'R', 'b2'UNION SELECT 4, 2, 'L', 'c1'UNION SELECT 5, 2, 'R', 'c2'UNION SELECT 6, 3, 'L', 'd1'UNION SELECT 7, 6, 'L', 'd2'UNION SELECT 8, 6, 'R', 'e1'IF OBJECT_ID('tempDb..#recurseMap') IS NOT NULL DROP TABLE #recurseMapCREATE TABLE #recurseMap ( [node] INT PRIMARY KEY , [treeDirection] CHAR(1) , [level] INT )DECLARE @startNode INT SET @startNode = 1DECLARE @level INT SET @level = 1DECLARE @rows INT SET @rows = 0-- Initial InsertINSERT #recurseMapSELECT [node], [position], @levelFROM #nodeMapWHERE [parent_node] = @startNode-- Recursive LoopSET @rows = @@ROWCOUNTSET @level = @level + 1WHILE ( @rows > 0 ) BEGIN INSERT INTO #recurseMap SELECT nm.[node] , rm.[treeDirection] , @level FROM #nodeMap AS nm JOIN #recurseMap AS rm ON rm.[node] = nm.[parent_node] WHERE rm.[level] = @level - 1 SET @rows = @@ROWCOUNT SET @level = @level + 1END-- ResultsSELECT @startNode AS [Start Node] , SUM(CASE WHEN [treeDirection] = 'L' THEN 1 ELSE 0 END) AS [Left] , SUM(CASE WHEN [treeDirection] = 'R' THEN 1 ELSE 0 END) AS [Right]FROM #recurseMap Charlie===============================================================Msg 3903, Level 16, State 1, Line 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
|
|
afroz
Starting Member
6 Posts |
Posted - 2010-09-18 : 02:11:26
|
Thanx charlie your code really worked thats what i needed...can u provide query with recursive functions (for 2008),i think these recursive functions are much faster than recursive while so..any way thank u very much for your help..afrozz.. |
|
|
|
|
|
|
|