我有桌子

   ID   MIN_ID
   1    1
   2    1
   3    1
   4    4
   5    1
   6    5
   7    6
   8    4

我需要第三列final_id,如果id=min_id,它将返回min_id,否则它将在表中递归查找,直到找到id=min_id的行。
   ID   MIN_ID  FINAL_ID
   1    1       1
   2    1       1
   3    1       1
   4    4       4
   5    1       1
   6    5       1        // 5 have the MIN_ID of 1
   7    6       1       // 6 have the MIN_ID of 1 and 5 have the MIN_ID of 1.
   8    4       4       // 8 goes to 4, 4 goes to 4. Done.

问题是,如果不在sql中使用任何过程语言,我如何才能得到这个结果。任何dbms示例都适合(mysql、postgresql、db2、sql server、oracle)
例如,执行此操作的php代码:
<?php

$table = [
    ['ID' => '1', 'MIN_ID' => '1'],
    ['ID' => '2', 'MIN_ID' => '1'],
    ['ID' => '3', 'MIN_ID' => '1'],
    ['ID' => '4', 'MIN_ID' => '4'],
    ['ID' => '5', 'MIN_ID' => '1'],
    ['ID' => '6', 'MIN_ID' => '5'],
    ['ID' => '7', 'MIN_ID' => '6'],
];


for ($x = 0; $x < count($table); $x++) {
    $table[$x]['FINAL_ID'] = calculate_final_id($table, $table[$x]);
}

print_r($table);


function calculate_final_id($table, $row)
{

    if ($row['ID'] == $row['MIN_ID']) {
        return $row['ID'];
    }

    $next_row = search($table, $row['MIN_ID']);

    return calculate_final_id($table, $next_row);
}

function search($table, $id)
{
    for ($x = 0; $x < count($table); $x++) {
        if ($table[$x]['ID'] == $id) {
            return $table[$x];
        }
    }
}

最佳答案

SQL Server示例。基于ID的顺序

CREATE TABLE myTable
    (ID int, MIN_ID int);

INSERT INTO myTable
    (ID, MIN_ID)
VALUES
    (1, 1),
    (2, 1),
    (3, 1),
    (4, 4),
    (5, 1),
    (6, 5),
    (7, 6)
;
WITH rc AS (
    SELECT ID, MIN_ID as FinalId
    FROM myTable
    UNION ALL
    SELECT rc.ID, t.MIN_ID
    FROM rc
    JOIN myTable t ON rc.FinalId = t.ID AND t.ID != t.MIN_ID
)
SELECT ID, min(FinalId) FinalId
FROM rc
GROUP BY ID;

08-17 19:26