Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8774287
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T18:31:36+00:00 2026-06-13T18:31:36+00:00

I have the following table structure, which is also on sqlfiddle for convenience: +———+———–+———+———-+———–+——————-+———————————–+——–+————–+————-+—————+———–+

  • 0

I have the following table structure, which is also on sqlfiddle for convenience:

+---------+-----------+---------+----------+-----------+-------------------+-----------------------------------+--------+--------------+-------------+---------------+-----------+
| rule_id | parent_id | left_id | right_id | rule_type | rule_title        | rule_description                  | public | parse_bbcode | parse_links | parse_smilies | group_ids |
+---------+-----------+---------+----------+-----------+-------------------+-----------------------------------+--------+--------------+-------------+---------------+-----------+
|       1 |         0 |       1 |        6 | cat       | Sample Category 1 |                                   |      1 |            0 |           0 |             0 | 1 2 7     |
|       2 |         1 |       2 |        3 | rule      | Sample Rule 1     | This is a sample rule description |      1 |            1 |           1 |             1 | 1 2 7     |
|       3 |         0 |       7 |        8 | cat       | Sample category 2 |                                   |      1 |            0 |           0 |             0 | 1 7 2     |
|       4 |         0 |       9 |       10 | cat       | Sample category 3 |                                   |      1 |            0 |           0 |             0 | 1 7 2     |
|       5 |         1 |       4 |        5 | rule      | Sample rule 3     | lol                               |      1 |            1 |           1 |             1 | 1 2 7     |
+---------+-----------+---------+----------+-----------+-------------------+-----------------------------------+--------+--------------+-------------+---------------+-----------+

As you see, rule_type can be either 'cat' or 'rule'.

cat stands for category, and categories are root nodes: so parent_id is always 0. In my code, we can identify categories by checking either if rule_type = 'cat' or parent_id = 0.

You can also see that I am using nested sets for my project and this is where the problem stands.

I have successfully created functions that:

  • move rules & categories up or down; and

  • put a new rule or category in the end of their respective place.

BUT I am failing to set the RULES’ right_id & left_id if we change its parent_id! I’m also failing to set right_id & left_id if we delete a rule OR category.

Example

I’ll try to explain with an example. Note that this is just an example, not the actual case and I need a general answer.

From the table above, we see that we have 3 categories with rule_id IN (1, 3, 4) and two rules with rule_id IN (2, 5).

The rule with rule_id = 2 is part of the category with rule_id = 1, we can see that from the parent_id column. What if I change the parent_id to 4? How would the right_id & left_id get set so everything is in place again? I know we need to update both rule_id IN (1, 4) to reorder everything, but I don’t know how my query would look like.

Same goes for deleting… For example I delete rule_id = 2 (which is a rule), how would I set right_id & left_id for parent_id = 1 in the correct order? Or when I delete a category? How would I reorder the categories?

I didn’t really try doing anything here, as I have no vision how I would do such a thing, therefore I’m asking for your help, folks.

I hope I made myself clear. If not, let me know and I’ll try to be even more descriptive.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-13T18:31:37+00:00Added an answer on June 13, 2026 at 6:31 pm

    I assume you have successfully set up the PDO connection.

    Also, be aware the following examples only work if all the categories are root nodes (like in the subject). It’s not a problem to change this code to work with nested categories.

    Deleting a rule

    1. Retrieve its right_id and left_id value.

    2. Delete row from the database.

    3. Update the table set right_id – 2 where right_id greater then the right_id of deleting rule.

    4. Same for left_id

    Example:

        $ruleIdForDel = 2;
        $leftId = 2;
        $rightId = 3;
    
        $pdo->beginTransaction();
        try {
            $pdo->exec("DELETE FROM rules WHERE rule_id = $ruleIdForDel");
            $pdo->exec("UPDATE rules
                        SET left_id = CASE
                                WHEN left_id > $leftId THEN left_id - 2
                                ELSE left_id
                            END,
                            right_id = CASE
                                WHEN right_id > $rightId THEN right_id - 2
                                ELSE right_id
                            END");
            $pdo->commit();
        } catch (Exception $e) {
            $pdo->rollBack();
            throw $e;
        }
    

    Updating rule’s parent_id

    Suppose we are going to move node to the last position of new parent

    1. Retrieve updating rule’s left_id and right_id ($ruleLeftId and $ruleRightId)

    2. Retrieve new parent rule’s left_id and right_id ($newParentRuleLeftId and $newParentRuleRightId)

    3. Check wether a node moving up or down the tree and depending on it generate new left_id and right_id values for the updating rule ($ruleNewLeftId and $ruleNewRightId)

    4. Update rules left_id and right_id depending on the updating rule’s destination

    5. Update parent_id, left_id, right_id of the updating rule

    If the updating rule’s right_key less then new parent rule’s right_id then the rule moves down the tree, otherwise it moves up the tree.

    If the rule moves down the tree we are going to shift left_id value by minus 2 on the rules located between the updating rule’s left_id ($ruleLeftId) and new left_id ($ruleNewLeftId) + 1. Otherwise, shift left_id value by 2 on the rules located between new left_id ($ruleNewLeftId) and initial left_id ($ruleLeftId).

    Same for right_id.

    Example:

        // Updating rule
        $ruleId = 2;
        $ruleLeftId = 2;
        $ruleRightId = 3;
    
        // New parent rule
        $newParentRuleId = 3;
        $newParentRuleLeftId = 7;
        $newParentRuleRightId = 8;
    
    
        // Generate new rule's left and right keys
        // Moves up
        if ($newParentRuleRightId < $ruleRightId) {
            $ruleNewLeftId = $newParentRuleRightId;
            $ruleNewRightId = $newParentRuleRightId + 1;
        // Moves down
        } else {
            $ruleNewLeftId = $newParentRuleRightId - 2; // 6
            $ruleNewRightId = $newParentRuleRightId - 1; // 7
        }
    
        $pdo->beginTransaction();
        try {
            $pdo->exec("UPDATE rules
                                SET left_id = CASE
                                    /* Moves down */
                                    WHEN $ruleNewRightId > $ruleRightId AND
                                         left_id > $ruleLeftId AND
                                         left_id <= $ruleNewLeftId + 1 THEN left_id - 2
                                    /* Moves up */
                                    WHEN $ruleNewRightId < $ruleRightId AND
                                         left_id >= $ruleNewLeftId AND
                                         left_id < $ruleLeftId THEN left_id + 2
                                    ELSE left_id
                                END,
                                right_id = CASE
                                    WHEN $ruleNewRightId > $ruleRightId AND
                                         right_id > $ruleRightId AND
                                         right_id <= $ruleNewRightId THEN right_id - 2
                                    WHEN $ruleNewRightId < $ruleRightId AND
                                         right_id >= $ruleNewLeftId AND
                                         right_id <= $ruleRightId THEN right_id + 2
                                    ELSE right_id
                                END");
            $pdo->exec("UPDATE rules
                        SET parent_id = $newParentRuleId,
                            left_id = $ruleNewLeftId,
                            right_id = $ruleNewRightId
                        WHERE rule_id = $ruleId");
            $pdo->commit();
        } catch (Exception $e) {
            $pdo->rollBack();
            throw $e;
        }
    

    I didnt use any PDO::Statement just to save space.

    I have not tested it properly so post an issue if you find some.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have the following table structure inside a view which gets displayed in the
I have the following table structure, which is imported into an Entity Framework project:
I have the following html structure (which is generated and I can't change): <table
I have the following table structure: ORGANIZATION_ID | Name | PARENT_ID -------------------------------------------------- 1 |
I have a table in database which has following structure(data) : +--------------------------+ Organization +--------------------------+
I have an asp.net gridview, which renders the following table structure: <table> <tr><th>Header 1</th><th>Header
I have two tables with the following (simplified) structures: table "Factors" which holds data
I have the following table structure: ID | fname | lname | street |
I have the following table structure (in MySQL): DocID, Code, IsDup, DopOf , where
I have the following table structure. A | B | C I wish to

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.