How to find all child rows in MySQL?

后端 未结 3 2000
再見小時候
再見小時候 2021-01-27 09:29

I have a hierarchy system setup that stores the level and parent ID of the item in a database. What I am trying to figure out is how would I go about finding all the child rows

相关标签:
3条回答
  • 2021-01-27 10:14

    Assuming you are on MySQL 5 that has triggers you can write a small before delete trigger to achieve this easily. I have not checked the syntax exactly but will match more or less with the following:

    CREATE TRIGGER tr_tablename_bd BEFORE DELETE ON tablename
      FOR EACH ROW BEGIN
        DELETE FROM tablename WHERE parentID = deleted.id
    END;
    

    The above code will also work with unlimited levels and not just 3 levels. You will need to delete a row and the trigger will delete the rows of data in the below levels or rows that mark the deleted row as parentID.

    I however, vaguely remember an issue with MySQL wherein it failed to launch cascaded triggers. Meaning MySQL fails to fire a trigger due to an action on another trigger. If that bug is still there in the release of MySQL you are using (or even the latest edition) then this code will not work. However, in theory it is perfectly ok and will work on every other database that has triggers for sure. For MySQL you just need to check up if they have managed to resolve that bug yet!

    0 讨论(0)
  • 2021-01-27 10:21

    Replace :id by the root entry id to be deleted in the following:

    DELETE FROM table
    WHERE
       id = :id 
       OR id IN (  
    -- first level
    SELECT DISTINCT id sid
    FROM table
    WHERE parentid = :id
    -- second level
    UNION
    SELECT DISTINCT t2.id sid
    FROM table t1
    INNER JOIN table t2
    ON t1.id = t2.parentid
    WHERE t1.parentid = :id
    -- third level
    UNION
    SELECT DISTINCT t3.id sid
    FROM table t1
    INNER JOIN table t2
    ON t1.id = t2.parentid
    INNER JOIN table t3
    ON t2.id = t3.parentid
    WHERE t1.id = :id
    )
    

    Note that you have 3 levels, but the root node occupies one of them, which means that you actually only need to select the children and grandchildren. The query above does one more level (the 3rd one), so you may remove the part after -- third level down to the closing parenthesis.

    0 讨论(0)
  • 2021-01-27 10:29

    Refer, Recursive MySQL Query with relational innoDB

    I had posted a answer yesterday for the same

    Update:

    Below is a function based on the above link, but has been tailored for your DELETE requirements

    CREATE PROCEDURE `delete_relations`(`_id` INT)
    BEGIN
    DECLARE  delete_row_ids varchar(200);
    DECLARE id, id2 varchar(200);
    DECLARE rows_affected int;
    
    SET delete_row_ids  = _id;
    SET id              = _id;
    SET id2             = id;
    
    WHILE id2 IS NOT NULL DO 
        SET id = NULL;
        SELECT GROUP_CONCAT( hierarchical_data.id ), CONCAT( GROUP_CONCAT( hierarchical_data.ID ),',',delete_row_ids) INTO id, delete_row_ids FROM hierarchical_data WHERE FIND_IN_SET( parentid , id2 ) GROUP BY parentid ;
        SET id2 = id;
    END WHILE;  
    
    DELETE FROM hierarchical_data where FIND_IN_SET(hierarchical_data.id, delete_row_ids);
    SELECT row_count() INTO rows_affected;
    
    if rows_affected > 0 THEN
    SELECT delete_row_ids as row_ids_deleted;
    ELSE
    SELECT 'NO_ROWS_DELETED';
    END IF;
    
    END//
    

    SQLFiddle

    Use

    CALL delete_relations(1)
    

    To delete all entries and its relations for id = 1 honda

    Hope its helpful

    0 讨论(0)
提交回复
热议问题