Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Jak przekonwertować hierarchię relacyjną na tabelę zamknięć w MySQL?

To jest starożytny skrypt, który ukończyłem 6-7 lat temu, aby wykonać to zadanie w PHP/Propel. Mam nadzieję, że przyda się to komuś innemu:

require_once 'common/Autoloader.php';
require_once 'propel/Propel.php';
\Propel::init('db/runtime-conf.php');

function truncateHierarchy(\PropelPDO $propel) {
    /* @var $state \PropelStatement */
    $state = $propel->prepare('TRUNCATE database.person_hierarchy');
    $state->execute();
}

function insertHierarchy(\PropelPDO $propel, $length) {
    if ($length == 0) {
        $state = $propel->prepare('INSERT INTO database.person_hierarchy SELECT id, id, 0 FROM person;');
        $state->execute();
        return $state->rowCount();
    } else if ($length == 1) {
        $state = $propel->prepare('INSERT INTO database.person_hierarchy SELECT parent_person_id, id, 1 FROM person WHERE id != parent_person_id;');
        $state->execute();
        return $state->rowCount();
    } else {
        $sql = "INSERT INTO database.person_hierarchy \n";
        $sql .= "SELECT p.parent_person_id, c" . ($length - 1) . ".id, " . $length . " FROM database.person AS p \n";
        for ($i = 1; $i <= $length - 1; $i++) {
            $sql .= "LEFT JOIN person AS c" . $i . " ON " . ($i == 1 ? 'p.id' : 'c' . ($i - 1) . '.id') . " = c" . $i . ".parent_person_id \n";
        }
        $sql .= "WHERE p.parent_person_id != p.id \n";
        for ($i = 1; $i <= $length - 1; $i++) {
            $sql .= "AND c" . $i . ".parent_person_id != c" . $i . ".id \n";
        }
        echo $sql;
        $state = $propel->prepare($sql);
        $state->execute();
        return $state->rowCount();
    }
}

/* @var $connect \PropelConnection */
$propel = \Propel::getConnection();
$propel->beginTransaction();

try {
    truncateHierarchy($propel);
    $propel->commit();
} catch (\Exception $e) {
    error_log_exc($e);
    echo "Failed to truncate person hierarchy!\n";
    $propel->rollBack();
    exit();
}

$length = 0;
$inserts = -1;
while ($inserts !== 0 || $length != 10) {
    $propel->beginTransaction();
    try {
        $inserts = insertHierarchy($propel, $length);
        if ($inserts == 0) { 
            echo "No persons exist at length " . $length . ".\n";
        } else {
            echo $inserts . " rows inserted for length " . $length . ".\n";
        }
        $length++;
        $propel->commit();
    } catch (\Exception $e) {
        error_log_exc($e);
        echo "Failed to regenerate person hierarchy!\n";
        $propel->rollBack();
        exit();
    }
}

echo "Regenerated person hierarchy!\n";
exit();



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jaki silnik mysql do ogromnej ilości danych (logowania)?

  2. Jak uciec ze słowa kluczowego value w mysql podczas korzystania z instrukcji Select

  3. MySQL i Matlab

  4. Mysql drukuje pomoc zamiast łączenia się z serwerem

  5. Czy korzystam z puli połączeń JDBC?