August 18, 2006 at 11:01 am
Hi all,
I have a situation where I need to return return data from the database in a tree-like manner. For example, I have a table called Questions, where the records contained in the database can either groups or questions, where questions will fall under groups (there is a column QuestionType that determines whether a record is a Question or Group).
So, I need a query that will get my all groups, and their sub-groups (if any) and the Questions that site under these groups (again, if any).
So some the structure of the output from the query should be like the following:
Group 1
----- Sub Group 1
---------- Question 1
---------- Question 2
----- Sub Group 2
---------- Question 1
Group 2
----- Sub Group 1
Group 3
----- Sub Group 1
---------- Question 1
---------- Question 2
---------- Question 3
Question 1
Question 2
Is this possible?
Hope you can help
Thanks
August 20, 2006 at 5:20 am
Maybe a snapshot of some data may help
QuestTreeUID ShortDesc LongDesc ParentUID QuestNodeUID
14SmartwasteSmartwaste 01
15Skip Skip 143
16Product Product 142
17MaterialMaterial 163
18Product Product 163
19FeedbackFeedback 142
20Origin of wasteOrigin of waste 193
21Cause Cause 193
When Questions with a QuestNodeUID of 1 is the parent (Inspection), QuestNodeTypeUID 2 is of type Group, and 3 is the actual Question. I'd like to format this data into an Output like I provided in my first post through SQL.
Thanks
August 20, 2006 at 3:55 pm
Probably what you need is simple XML out of you data.
_____________
Code for TallyGenerator
August 20, 2006 at 10:21 pm
The QuestNodeUID made this a real pain in the hiney... the following is a complete test showing what you want... this has a "limited" range of hierarchies but will probably handle whatever you throw at it...
--===== If the temporary demonstration tables exist, drop them
IF OBJECT_ID('TempDB..#MyHead') IS NOT NULL
DROP TABLE #MyHead
IF OBJECT_ID('TempDB..#Hierarchy') IS NOT NULL
DROP TABLE #Hierarchy
--===== Create the table to hold the data posted for test
CREATE TABLE #MyHead
(
QuestTreeUID INT PRIMARY KEY CLUSTERED,
ShortDesc VARCHAR(20),
LongDesc VARCHAR(20),
ParentUID INT,
QuestNodeUID INT
)
--===== Populate the table with the test data posted
INSERT INTO #MyHead(QuestTreeUID,ShortDesc,LongDesc,ParentUID,QuestNodeUID)
SELECT 14,'Smartwaste','Smartwaste',0,1 UNION ALL
SELECT 15,'Skip','Skip',14,3 UNION ALL
SELECT 16,'Product','Product',14,2 UNION ALL
SELECT 17,'Material','Material',16,3 UNION ALL
SELECT 18,'Product','Product',16,3 UNION ALL
SELECT 19,'Feedback','Feedback',14,2 UNION ALL
SELECT 20,'Origin of waste','Origin of waste',19,3 UNION ALL
SELECT 21,'Cause','Cause',19,3
--===== Test setup complete, we're ready to rock!
--===== Create and preset a level counter.
DECLARE @CurrentLevel INT
SET @CurrentLevel = 0
--===== Create the Hierarchy table
CREATE TABLE #Hierarchy
(
QuestTreeUID INT PRIMARY KEY,
ParentUID INT,
Level INT,
Hierarchy VARCHAR(8000),
QuestNodeUID INT
)
--===== Seed the Hierarchy table with the top level
INSERT INTO #Hierarchy
(QuestTreeUID,ParentUID,Level,Hierarchy,QuestNodeUID)
SELECT QuestTreeUID,
ParentUID,
0 AS Level,
STR(QuestTreeUID,7)+' ' AS Hierarchy,
QuestNodeUID
FROM #MyHead
WHERE ParentUID =0
--===== Determine the rest of the hierarchy
WHILE @@ROWCOUNT > 0
BEGIN
SET @CurrentLevel = @CurrentLevel + 1 --Started at 0
INSERT INTO #Hierarchy
(QuestTreeUID,ParentUID,Level,Hierarchy,QuestNodeUID)
SELECT p.QuestTreeUID,
p.ParentUID,
@CurrentLevel AS Level,
CASE
WHEN p.QuestNodeUID IN (1,2)
THEN h.Hierarchy + STR(p.QuestTreeUID,7)+' '
ELSE h.Hierarchy + STR(9999999,7)
END AS Hierarchy,
p.QuestNodeUID
FROM #MyHead p
INNER JOIN #Hierarchy h
ON p.ParentUID = h.QuestTreeUID
AND h.Level = @CurrentLevel - 1
END
--===== Produce the hierarchical report
SELECT REPLICATE('-----',h.Level)+SPACE(SIGN(h.Level))+ p.ShortDesc
FROM #MyHead p,
#Hierarchy h
WHERE NOT (h.Level = 1 AND h.QuestNodeUID = 3) --Skips out of line entries
AND p.QuestTreeUID = h.QuestTreeUID
ORDER BY h.Hierarchy
Please send beer... I already have enough pretzels
--Jeff Moden
Change is inevitable... Change for the better is not.
September 4, 2006 at 8:58 am
Thank you very much for this Jeff. I forgot about my post, but just remembered it as I need it.
Top stuff
September 4, 2006 at 9:21 am
Thanks Trystan,
Looking back at it, one of the CASE statements is simply overkill... replacing this part should also work with a tiny bit more speed...
--===== Determine the rest of the hierarchy
WHILE @@ROWCOUNT > 0
BEGIN
SET @CurrentLevel = @CurrentLevel + 1 --Started at 0
INSERT INTO #Hierarchy
(QuestTreeUID,ParentUID,Level,Hierarchy,QuestNodeUID)
SELECT p.QuestTreeUID,
p.ParentUID,
@CurrentLevel AS Level,
h.Hierarchy + STR(p.QuestTreeUID,7)+' ' AS Hierarchy,
p.QuestNodeUID
FROM #MyHead p
INNER JOIN #Hierarchy h
ON p.ParentUID = h.QuestTreeUID
AND h.Level = @CurrentLevel - 1
END
--Jeff Moden
Change is inevitable... Change for the better is not.
Viewing 6 posts - 1 through 5 (of 5 total)
You must be logged in to reply to this topic. Login to reply