1

この画像は、私が達成しようとしていることを示しています。左側がテーブル データ、右側が作成しようとしているテーブルです。

テーブルは、parentID を使用して同じテーブル内の別の項目を参照し、階層を作成します。

このようにクエリを作成して整理するにはどうすればよいでしょうか。

「Pirates」を選択して、すべての親を取得したい場合はどうすればよいですか? 一番上に到達するまでクエリをループするよりも簡単にする CFML の機能はありますか?

ここに画像の説明を入力

4

4 に答える 4

2

階層データは、隣接リストと呼ばれる方法を使用して表されます。他にも多くのオプションがありますが、最終的に使用するオプションは、データが変更される頻度と使用している基礎となるデータベースによって異なります。隣接リストのクエリを容易にする機能を備えているものもあります。その中で最も重要なのは共通テーブル式(CTE) です。他のデータベースでそれを行う方法については、リンクされている質問を参照してください。

CTEを使用すると、隣接リストから階層を順番に取得し、各エントリの「レベル」を計算できます-あなたの場合、正しくインデントします。データベースに CTE がなく、簡単にクエリを実行する別の方法がない場合は、別のアプローチを使用することを検討してください。ネストされたセットはおそらく最もアクセスしやすく、取得は高速ですが、より複雑な変更アルゴリズム (つまり、挿入、削除、削除など) が犠牲になります。動く)。

于 2011-06-22T23:27:09.930 に答える
1

私はこれをテストしていません... :)

<!--- item.cfc --->
<cfcomponent persistent="true" cache="read-only">
    <cfproperty name="id" fieldtype="id">
    <cfproperty name="parent"
                fieldtype="many-to-one" cfc="item" fkcolumn="ParentID">
    <cfproperty name="children" type="array"
                fieldtype="one-to-many" cfc="item" fkcolumn="ParentID" inverse="true">
</cfcomponent>

<!--- display.cfm --->
<cffunction name="printItem" output="true">
    <cfargument name="item" required="true">
    <table>
        <tr>
        <td>#item.getName()#

        <cfif item.hasChildren()>
            <table>
              <cfloop array="#item.getChildren()#" index="local.i">
                  <tr>
                      <td>#printItem(local.i)#
              </cfloop>
            </table>
        </cfif>
    </table>
</cffunction>

<cfset printItem( entityLoadByPK("item",1) )>
于 2011-06-22T23:10:13.533 に答える
0

これは私があなたの助けを借りて思いついたものです.

<!--- adjacency list display --->
<cffunction name="adjacentList" output="true">
    <cfargument name="alQuery" required="true">
    <cfargument name="qid" required="false" default="0">

        <cfquery name="alSubQuery" dbtype="query">
            SELECT * FROM alQuery WHERE parentID=#qid#
        </cfquery>

        <cfif alSubQuery.RecordCount neq 0>
            <ul>
            <cfloop query="alSubQuery">
                <li>
                #name#
                #adjacentList(#alQuery#,#id#)#
                </li>
            </cfloop>
            </ul>
        </cfif>
</cffunction>

使用:#adjacentList(#query#)#

于 2011-06-23T21:46:47.643 に答える
0

同様の必要性を考えたときに私が検討したアプローチの 1 つは、階層を非同期的に (つまり、AJAX 要求を使用して) 構築することです。必要に応じて、これが機能する場合と機能しない場合がありますが、ツリー全体をすぐに構築するのではなく、最初に最上位レベルのみをユーザーに提示することを想像してください。次に、ユーザーがトップ レベルの項目の 1 つを選択すると、選択した項目の子を見つけるために AJAX 要求が行われます。必要に応じて、各子供がツリーを構築するのを繰り返します。このようにすると、問題は非常に単純になり、それを実装するために使用されるクエリとコードも非常に単純になります。

于 2011-06-23T18:07:08.647 に答える