Folders within folders query
Hi I have a database which is basically documents and folders. I want to produce an SQL to show the location of a particular document/folder. What I have come up with so far is this: select d.name, f1.name, f2.name, f3.name, f4.name, f5.name from documents d left join folders f1 on d.id_parent=f1.id_object left join folders f2 on f1.id_parent=f2.id_object left join folders f3 on f2.id_parent=f3.id_object left join folders f4 on f3.id_parent=f4.id_object left join folders f5 on f4.id_parent=f5.id_object where d.id_object = '58964987' This gives me the info I need but is slow to run – is this the best way of doing this? Also this only gives 5 locations – it could be that the document/folder could have 15 – would I need to then do this up to folder 15 or is there a better way? I was also wishing to list all document in a particular folder and within any folders within that folder. I deleted where d.id_object = '58964987' and added this to the above: where (d.id_parent = 'fA19780' or f1.id_parent = 'fA19780' or f2.id_parent = 'fA19780' or f3.id_parent = 'fA19780') Again this gave me what I needed but was slow and if I went upto 15 layers of folder I would have to add and type this 15 times – is there a better way? Many thanks Paul Hi I have a database which is basically documents and folders. I want to produce an SQL to show the location of a particular document/folder. What I have come up with so far is this: select d.name, f1.name, f2.name, f3.name, f4.name, f5.name from documents d left join folders f1 on d.id_parent=f1.id_object left join folders f2 on f1.id_parent=f2.id_object left join folders f3 on f2.id_parent=f3.id_object left join folders f4 on f3.id_parent=f4.id_object left join folders f5 on f4.id_parent=f5.id_object where d.id_object = '58964987' This gives me the info I need but is slow to run – is this the best way of doing this? Also this only gives 5 locations – it could be that the document/folder could have 15 – would I need to then do this up to folder 15 or is there a better way? I was also wishing to list all document in a particular folder and within any folders within that folder. I deleted where d.id_object = '58964987' and added this to the above: where (d.id_parent = 'fA19780' or f1.id_parent = 'fA19780' or f2.id_parent = 'fA19780' or f3.id_parent = 'fA19780') Again this gave me what I needed but was slow and if I went upto 15 layers of folder I would have to add and type this 15 times – is there a better way? Many thanks Paul
April 28th, 2011 12:59pm

The problem with the approach your taking is that you will always be limited to the pre-determined number of levels you built into the query If your report is only looking for the path of one folder at a time, I think you'd have better luck with an approach more like this one... DECLARE @Object INT, @Parent INT, @Path VarChar(MAX), @Object2 INT SET @Object = 2028 SELECT @Parent = id_parent FROM Documents WHERE id_object = @Object SELECT @Path = Name FROM Documents WHERE id_object = @Object SET @Object2 = @Object WHILE @Parent IS NOT NULL BEGIN SET @Object = @Parent SELECT @Parent = id_parent FROM Documents WHERE id_object = @Object SELECT @Path = Name + ' > ' + @Path FROM Documents WHERE id_object = @Object END SELECT @Object2 AS id_object, @Path AS Object_Path This will produce 2 columns id_object & Object_Path. The Object_Path will be formatted like this... Top Level Object > Second Level Object > Third Level Object > Fourth Level Object > The Object Being Queried The advantage here is that it doesn't matter how many levels there in the path, you'll never have too many or too few columns to accommodate the data. Jason Long
Free Windows Admin Tool Kit Click here and download it now
April 28th, 2011 4:14pm

Hi Jason Im not in work for about a week now so created a test database at home with just 2 table like below: Folders: 1 Global Folder NULL 100 Test Folder1 1 634 Paul 100 671 Paul2 634 747 Hayley 100 749 Hayley2 747 101010 Test2 100 101013 Test3 100 150 HR 1 160 Staff 150 164 Current 160 173 Former 160 190 Security 150 Documents 111 Paul Doc 749 When using your SQL I get no results - executes for ever but no results are produced. Am i doing something stupid?!! Many thanks Paul
April 29th, 2011 12:55pm

Paul, I have to head to lunch right now but I'll take a look as soon as I get back. Jason Long
Free Windows Admin Tool Kit Click here and download it now
April 29th, 2011 12:59pm

I'm not sure where you're having problems. I just took it for a test drive and it worked just fine... -- Place the test data into a temp table -- IF OBJECT_ID('tempdb..#Documents') IS NOT NULL DROP TABLE #Documents CREATE TABLE #Documents (id_object INT, Name VarChar(25), id_parent INT) INSERT INTO #Documents SELECT 1 AS id_object, 'Global Folder' AS Name, NULL AS id_parent UNION ALL SELECT 100,'Test Folder1', 1 UNION ALL SELECT 634,'Paul', 100 UNION ALL SELECT 671,'Paul2', 634 UNION ALL SELECT 747,'Hayley', 100 UNION ALL SELECT 749,'Hayley2', 747 UNION ALL SELECT 101010,'Test2', 100 UNION ALL SELECT 101013,'Test3', 100 UNION ALL SELECT 150,'HR', 1 UNION ALL SELECT 160,'Staff', 150 UNION ALL SELECT 164,'Current', 160 UNION ALL SELECT 173,'Former', 160 UNION ALL SELECT 190,'Security', 150 -- The actual solution -- DECLARE @Object INT, @Parent INT, @Path VarChar(MAX), @Object2 INT SET @Object = 671 --(enter the id_object for Paul2) SELECT @Parent = id_parent FROM #Documents WHERE id_object = @Object SELECT @Path = Name FROM #Documents WHERE id_object = @Object SET @Object2 = @Object WHILE @Parent IS NOT NULL BEGIN SET @Object = @Parent SELECT @Parent = id_parent FROM #Documents WHERE id_object = @Object SELECT @Path = Name + ' > ' + @Path FROM #Documents WHERE id_object = @Object END -- And the final SELECT -- SELECT @Object2 AS id_object, @Path AS Object_Path And here is the result... id_object Object_Path 671 Global Folder > Test Folder1 > Paul > Paul2 Let me know if you have any more problems.Jason Long
April 29th, 2011 2:20pm

Hi Jason sorry for the late reply-my laptop and a glass of water had a fight and my laptop came off worse! Using the temp table way work fine for me. the question i have is would this also work with 2 tables 'Documents' &'Folders'? I want to be able to search for a document ID in the Documents table and then list the folder location from the Folders table. just to clarify the document has its own id and then parent id which is the id of the first folder. many thanks Paul ps sorry for typing-im using the on-screen keyboard!
Free Windows Admin Tool Kit Click here and download it now
May 1st, 2011 6:34am

Paul, If you want to post some sample data, structured the way it is in your system, I can show you how to rewrite the query. Jason Long
May 1st, 2011 12:28pm

Hi Jason Many thanks for your reply. If we take the example from before we have a table called 'Folders' which contains the following data: id_object Name id_parent 1 Global Folder NULL 100 Test Folder1 1 634 Paul 100 671 Paul2 634 747 Hayley 100 749 Hayley2 747 101010 Test2 100 101013 Test3 100 150 HR 1 160 Staff 150 164 Current 160 173 Former 160 190 Security 150 and a table called 'Documents' with data like: id_object name id_parent 111 Paul Doc 749 what i would like is to be able to type the doc id 111 and the location (hayley2,hayley,test folder1,global folder) to be given. Many thanks Paul
Free Windows Admin Tool Kit Click here and download it now
May 1st, 2011 1:35pm

Well in that case you'd SET @Object = 749. The result would be... id_object Object_Path 749 Global Folder > Test Folder1 > Hayley > Hayley2 If you want the output formatted the wat you have it in your last post... (hayley2,hayley,test folder1,global folder) You just need to make a minor modification to line #30 SELECT @Path = @Path + ', ' + Name FROM #Documents WHERE id_object = @Object Now the results read like this... id_object Object_Path 749 Hayley2, Hayley, Test Folder1, Global Folder If you want to use the "111" id, you'll need to union the two tables. If you post the table structure of both tables I can show you how to do that too.Jason Long
May 2nd, 2011 9:55am

Try it like this... DECLARE @Union TABLE ( id_object INT NOT NULL, name VarChar(50) NOT NULL, id_parent INT NULL) INSERT INTO @Union SELECT id_object, name, id_parent FROM Folders UNION ALL SELECT id_object, name, id_parent FROM Documents DECLARE @Object INT, @Parent INT, @Path VarChar(MAX), @Object2 INT SET @Object = 111 --(enter the id_object for PaulDoc) SELECT @Parent = id_parent FROM @Union WHERE id_object = @ObjectSELECT @Path = '' SET @Object2 = @Object WHILE @Parent IS NOT NULL BEGIN SET @Object = @Parent SELECT @Parent = id_parent FROM @Union WHERE id_object = @Object SELECT @Path = @Path + ', ' + Name FROM @Union WHERE id_object = @ObjectEND SELECT @Object2 AS id_object, RIGHT(@Path, LEN(@Path) -1) AS Object_Path Jason Long
Free Windows Admin Tool Kit Click here and download it now
May 2nd, 2011 10:16am

Hi Jason Would it make difference if the document id was like 'A111' and folder id was like 'F247' Using the second one I get the error that #documents does not exist. If I delete the # and keep the documents it runs but again gives no results. If i use the temp table you setup it worked but I think that is because all the info is in the one table - 'documents' and not 'Documents' and 'Folders' So to be a pain! and sorry if im not explaining myself well. Thanks Paul
May 2nd, 2011 12:19pm

>> Using the second one I get the error that #documents does not exist. If I delete the # and keep the documents it runs but again gives no results. If i use the temp table you setup it worked but I think that is because all the info is in the one table - 'documents' and not 'Documents' and 'Folders' Look at it again. I've replace the #Documents with @Union. >> Would it make difference if the document id was like 'A111' and folder id was like 'F247'? Nope. Not as long as you make the necessary datatype adjustments. Look up the 2 tables in SSMS's Object Explorer and drill down to the Columns folder level. It will show the data types currently being used for those columns. Scan through the script from my last post and replace all of the instances where I've defined a data type as INT and change it. >> So to be a pain! and sorry if im not explaining myself well. No worries. Just bear in mind, for future reference, the more accurate you are upfront with the details... The easier it is for someone to give you a good solid answer and get it to you quicker. When you post your question as a hypothetical, the answer you can expect will also be hypothetical. Providing real table names, real column names and their actual data types makes the process far smoother. Obviously you can't provide real sample data for security reasons, but the made up sample data should at least be representative (in terms of structure) of the real data.Jason Long
Free Windows Admin Tool Kit Click here and download it now
May 2nd, 2011 1:02pm

Hi Jason Many thanks for your help. Looks like this is now working for me. Just one quick question more out if curiosity than anything else. Is creating the @Union table the same as creating a temp table? Next time I'll make sure ill be more accurate with my data up front. Point taken about being able to provide real columns and table names but not real data. Think I was just trying to be too cautious. Once again thanks for your help. Paul
May 3rd, 2011 2:11am

>> Many thanks for your help. Looks like this is now working for me. Glad you got it working! >> Just one quick question more out if curiosity than anything else. Is creating the @Union table the same as creating a temp table? Very similar in several ways, but no. The @Union is a table variable. If you Google "sql server difference between temp table and table variable", you'll find plenty of information on both the differences and similarities. For the record... A temp table would have worked equally well in this particular situation. I just chose to use a table variable due to the simplified syntax. >> Next time I'll make sure ill be more accurate with my data up front. Point taken about being able to provide real columns and table names but not real data. Think I was just trying to be too cautious. Like I said, no worries. Just something to keep in mind. Sometimes it's tough to know which details are important for answering your question and erroring on the side of caution isn't a bad thing. >> Once again thanks for your help. You're welcome. :-) Jason Long
Free Windows Admin Tool Kit Click here and download it now
May 3rd, 2011 10:05am

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics