Results 1 to 4 of 4

Thread: Recursive MYSQL Query

  1. #1
    Join Date
    Mar 2003
    Posts
    1

    Recursive MYSQL Query

    I have a MYSQL db that holds all of my family information. In the db, I'm tracking parent/child relationships as well as husband/wife relationships. Here are the relevant columns in my table for this question:
    TABLE NAME - PERSON
    P_ID
    P_FIRSTNAME
    P_BIRTHDAY
    P_PARENT_ID
    P_SPOUSE_ID

    I've created a PHP calendar on which I want to show family member's birthdays. The thing is, I only want to see birthdays for family members where the relation is not too distant (as much as I love my third and fourth cousins, I don't think I care much about their b-days). The site requires a login so at any given time I have the P_ID for the person logged in.

    I want to select the following relationships for any person that logs in.
    1.) My birthday
    2.) My children's birthdays
    3.) My children's children's birthdays (grandkids)
    4.) My parents
    5.) My parent's children (my siblings)
    6.) My parent's children's children (my nieces & nephews)

    I know I could jimmy-rig this and just run one select to get my kids. Then in PHP, loop through those results and for each child run another select to get their children. Then do the same thing using my parents as the starting point. I am looking for a better MYSQL query than this. I think I can be done in one query, or two at the most (one for me, my kids, and grandkids; and one for parents, their kids and grandkids).

    To simplify matters, really all I need to find out is given a P_ID, how can I find that P_ID's children and grandchildren?

    If I start my select
    SELECT P_ID, P_FIRSTNAME, P_BIRTHDAY
    FROM PERSON
    WHERE P_PARENT_ID = $myId
    (this gets all my kids. now I need to do some kind of 'foreach' of my kids, find their kids)

    I hope this is enough details. Thanks in advance

  2. #2
    Join Date
    Nov 2002
    Location
    New Jersey, USA
    Posts
    3,932
    I have not worked with MySQL, but this kind of query is possible in Oracle using "Connect By" clause.

    In SQL Server, you need to use cursor and temp table to push/pop current record and find the child records.

    This is from SQL Server books online. You can write something like this

    ---
    CREATE PROCEDURE expand (@current char(20)) as
    SET NOCOUNT ON
    DECLARE @level int, @line char(20)
    CREATE TABLE #stack (item char(20), level int)
    INSERT INTO #stack VALUES (@current, 1)
    SELECT @level = 1

    WHILE @level > 0
    BEGIN
    IF EXISTS (SELECT * FROM #stack WHERE level = @level)
    BEGIN
    SELECT @current = item
    FROM #stack
    WHERE level = @level
    SELECT @line = space(@level - 1) + @current
    PRINT @line
    DELETE FROM #stack
    WHERE level = @level
    AND item = @current
    INSERT #stack
    SELECT child, @level + 1
    FROM hierarchy
    WHERE parent = @current
    IF @@ROWCOUNT > 0
    SELECT @level = @level + 1
    END
    ELSE
    SELECT @level = @level - 1
    END -- WHILE

  3. #3
    Join Date
    Dec 2002
    Location
    Cape Town, South Africa
    Posts
    75
    Your simple request is possible, as I understand it. Given a simplified data set:
    Code:
    SELECT * FROM parents;
    +------+--------------+-------------+
    | P_ID | P_NAME       | P_PARENT_ID |
    +------+--------------+-------------+
    |    1 | me           |           2 |
    |    2 | dad          |           3 |
    |    3 | granddad     |        NULL |
    |    4 | moi          |        NULL |
    |    5 | kiddie1      |           4 |
    |    6 | kiddie2      |           4 |
    |    7 | grandkiddie1 |           5 |
    +------+--------------+-------------+
    You can return all of the kids and grandkids for 'moi' with the following:
    Code:
    SELECT p2.P_NAME as kids 
    FROM parents AS p1, parents AS p2 
    WHERE p1.P_ID = p2.P_PARENT_ID 
    AND (p1.P_ID=4 OR p1.P_PARENT_ID=4);
    +--------------+
    | kids         |
    +--------------+
    | kiddie1      |
    | kiddie2      |
    | grandkiddie1 |
    +--------------+

  4. #4
    Join Date
    Jul 2006
    Posts
    1
    Getting the children + grandchildren works for those two levels because you are storing P_ID and P_PARENT_ID (two levels: current + one above) If you need three levels then you can store the third level (ie, P_GPARENT_ID).

    I don't recommend this as there are cases where you want the "(n*great) grandparent" of a row (ie, n=1: great grandparent, n=2: great great grandparent) and it becomes inefficient to store the nth great grandparent as a separate column.

    The alteratives (storing hierarchical data) have been discussed in many places, and I have put some of those together with a bit of commentary.

    http://jgeewax.wordpress.com/2006/07...onal-database/

Posting Permissions

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