4

これを行う簡単な方法があることは知っていますが、私の再帰能力は実践的ではありません。3 つのフィールドを持つデータベース テーブルがあるとします。

id
label
child_id

次のような出力を与える再帰関数をまとめることができるはずです。

child (input of program)
  parent1
  parent2
    grandparent1
      great-grandparent1
    grandparent2
    grandparent3
  parent3
    grandparent4
    grandparent5

簡単なはずなのに、頭の体操をしてうまくいかない。また、これは良いことですか?かなりの数のデータベース接続を開いたままにしてしまう可能性があるようです。

これが私を難しくしている部分だと思います。私は child_id から始めて、上に向かって進んでいます。そして、子供は多くの親を持つことができます。したがって、出力はツリーの「ルート」にある子 ID になり、次に各ブランチの親と祖父母になります。考えれば考えるほど、セマンティクスを除いて、伝統的な「親は 1 人、祖父母は多数」の公式にすぎません。私はそれを考えすぎている可能性があります。

テーブルは次のようになります。

table parents

id    child_id    label
 1     NULL       child
 2     1          parent1
 3     1          parent2
 4     1          parent3
 5     3          grandparent1
 6     3          grandparent2
 7     3          grandparent3
 8     5          great-grandparent1
 9     4          grandparent4
10     4          grandparent5
4

2 に答える 2

3

あなたはこの方法を試すことができます

sub getChildren {
  my $id = shift;
  my $depth = shift;
  my $sql = qq/SELECT id,label,child_id FROM table WHERE id=?/;
  my $sth = $db->prepare($sql);
  my $sth->execute($id);
  while(my ($id,$label,$child_id)=$sth->fetchrow_array) {
    print " "x$depth,$label;
    getChildren($child_id,$depth++);
 }
}
getChildren($id);
于 2010-06-25T18:58:47.383 に答える
0

私は実際に私のブログで非常によく似た問題を説明しました。 PostgreSQL ストアド プロシージャで深さ優先検索を実装し、 perl を使用してこれを解決する方法です。

データベースがストアド プロシージャをサポートしていない場合は、同じことをクライアント側で実行できますが、最初にテーブル全体をフェッチしてメモリ内で実行する必要があります。

もちろん、再帰的に実行して各エントリをフェッチすることもできますが、SQL ステートメントのオーバーヘッドのためにスケーリングされません (おそらく SQLite を除く)。パフォーマンスに問題がない場合は、これが最も簡単な解決策です。

于 2010-06-27T15:00:20.253 に答える