Results 1 to 13 of 13

Thread: SQL Challenge... Trees?

  1. #1

    Thread Starter
    PowerPoster rjlohan's Avatar
    Join Date
    Sep 2001
    Location
    Sydney, Australia
    Posts
    3,205

    Question SQL Challenge... Trees?

    I want to store in a single table in a database, a sort of tree structure. I have the relationships and the table all set up, but I want to be able to retrieve data in a special way.

    Table Schema:
    [Categories]
    catID: PK
    catText
    superCatID: FK (Relates to catID, is not compulsory)


    So, in a table, I may have the following data:

    catID catText superCatID
    1 General
    2 Test1 1
    3 Test2 1
    4 Test3 2


    Now, if the user wants category 4, I want to retrieve the entire chain that 4 inherits:
    4 Test3 2
    2 Test1 1
    1 General


    As you can see, catID(2) is the parent of catID(4), and catID(1) is the parent of catID(2).





    Now, can this be done??

    -----------------------------------------
    -RJ
    [email protected]
    -----------------------------------------

  2. #2
    Frenzied Member pnish's Avatar
    Join Date
    Aug 2002
    Location
    Tassie, Oz
    Posts
    1,918
    This isn't too hard to do in VB. Depending on how deeply nested the data set is I would use recursion, ie a routine that calls itself.

    VB Code:
    1. Public Sub GetCat(ByVal cat As Long)
    2.    
    3.     Dim rs As Recordset
    4.     Dim catid As Long
    5.     Dim sql As String
    6.     sql = "select * from [cat] where [CatID]=" & cat
    7.    
    8.     Set rs = db.OpenRecordset(sql, dbOpenSnapshot)
    9.        
    10.     If rs.RecordCount > 0 Then
    11.         Debug.Print rs!catid, rs!cattext, rs!supercatid
    12.         If IsNull(rs!supercatid) Then
    13.             catid = -1
    14.         Else
    15.             catid = rs!supercatid
    16.         End If
    17.         rs.Close
    18.         Set rs = Nothing
    19.         GetCat catid    ' Re-cursive call
    20.         Exit Sub
    21.     End If
    22.    
    23.     rs.Close
    24.     Set rs = Nothing
    25.    
    26. End Sub

    So if you wanted category 4 and all its children you would call the GetCat sub with a value of 4. This bit of code is using DAO but it could just as easily use ADO if you're accessing SQL Server etc.

    This code also isn't very efficient, opening & closing the data source with each iteration. I'm sure you'll find a better way to do it.

    Cheers

  3. #3

    Thread Starter
    PowerPoster rjlohan's Avatar
    Join Date
    Sep 2001
    Location
    Sydney, Australia
    Posts
    3,205
    Probably a faster way, along the same lines would be to retrieve the whole table (shouldn't be too big) and sort a disconnected recordset, or array.

    I was hoping for a SQL query that would cover this though...
    -----------------------------------------
    -RJ
    [email protected]
    -----------------------------------------

  4. #4

    Thread Starter
    PowerPoster rjlohan's Avatar
    Join Date
    Sep 2001
    Location
    Sydney, Australia
    Posts
    3,205
    Hmmm no luck yet. Have tried shaped recordsets, but can't work out how to get the right tree...
    -----------------------------------------
    -RJ
    [email protected]
    -----------------------------------------

  5. #5
    Frenzied Member pnish's Avatar
    Join Date
    Aug 2002
    Location
    Tassie, Oz
    Posts
    1,918
    Originally posted by rjlohan
    Hmmm no luck yet. Have tried shaped recordsets, but can't work out how to get the right tree...
    Are you still trying to do this with a SQL query? I haven't had heaps of experience with complex queries (which I think this would be) so I'm not sure I can help other than to point you back to the code I posted earlier.

    I know this code works (well it worked on the small data set I tested it against anyway).

    There's gotta be a SQL guru on these forums somewhere.

    Cheers

  6. #6

    Thread Starter
    PowerPoster rjlohan's Avatar
    Join Date
    Sep 2001
    Location
    Sydney, Australia
    Posts
    3,205
    I can do it with code, but I don't want to if I can get away with it.
    -----------------------------------------
    -RJ
    [email protected]
    -----------------------------------------

  7. #7
    Frenzied Member pnish's Avatar
    Join Date
    Aug 2002
    Location
    Tassie, Oz
    Posts
    1,918
    When I get a spare moment I'll see if I can come up with any ideas. In the meantime, don't hold your breath!

    I'm sure that recursion is the secret. It's just a matter of figuring out a way of doing it in SQL, a stored procedure perhaps.

    As I said, I'm no SQL guru, but there's gotta be a way.

    Cheers

  8. #8

    Thread Starter
    PowerPoster rjlohan's Avatar
    Join Date
    Sep 2001
    Location
    Sydney, Australia
    Posts
    3,205
    Cool. Good luck. I'm still pluggin'.
    -----------------------------------------
    -RJ
    [email protected]
    -----------------------------------------

  9. #9
    Fanatic Member
    Join Date
    Jan 1999
    Location
    UK
    Posts
    593
    What we do in vBulletin is we store a 'parent list' field. This contains a comma delimited list of ids of all the parent categories.

    So you might have:
    Code:
    catID	catText	parentList
    1	General	,1,
    2	Test1	,1,2,
    3	Test2	,1,3,
    4	Test3	,1,2,4,
    Then the parent list field can be used to grab all the parents of a particular category.

  10. #10

    Thread Starter
    PowerPoster rjlohan's Avatar
    Join Date
    Sep 2001
    Location
    Sydney, Australia
    Posts
    3,205
    That's a possibility, although causes a fair bit of data redundancy. I will consider it though. Cheers.

    -----------------------------------------
    -RJ
    [email protected]
    -----------------------------------------

  11. #11
    Lively Member
    Join Date
    Mar 2002
    Location
    S.A
    Posts
    89
    I had the same problem once... but this www helped me allot. A small change to the db and it works 10000%... and fast.

    http://www.intelligententerprise.com...celko1_1.shtml

    Study the example... look weird in the begining... but its great !

    That is not the exact one i wanted to show you.. but here is one more

    http://www.aspalliance.com/Mamanze/a...h=sqlrecursive

    I'll post the 100% correct one (if i can find it)
    Last edited by Sundance Kid V2; Sep 11th, 2002 at 08:33 AM.
    I forgot my password....

  12. #12

    Thread Starter
    PowerPoster rjlohan's Avatar
    Join Date
    Sep 2001
    Location
    Sydney, Australia
    Posts
    3,205
    That looks like it may be what I want.

    Cheers,
    RJ

    -----------------------------------------
    -RJ
    [email protected]
    -----------------------------------------

  13. #13

    Thread Starter
    PowerPoster rjlohan's Avatar
    Join Date
    Sep 2001
    Location
    Sydney, Australia
    Posts
    3,205
    After much stuffing around, have gotten really sick of this one, and fallen back on this solution.

    As catID is an AutoNumber field, no new category can have a superCatID > catID.

    So, I've decided the easiest solution is to just retrive the recordset order in reverse catID, from the requested catID and lower.

    Then, with one pass, I can build the tree.

    Simple. Wish I'd though of it before...
    -----------------------------------------
    -RJ
    [email protected]
    -----------------------------------------

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width