1

次の COMPLEX タスクの SQL クエリが必要です...

という名前の列から選択する必要がありますparent_id。行に 0 があるparent_id場合は、それがカテゴリであることを意味します (カテゴリを示すtype列もありcatます)。行に 1 以上parent_idある場合は、それがルールであることを意味します。parent_idルールの は、rule_idカテゴリの です。

いくつかのデータを含むテーブル構造: phpMyAdmin テーブル データ

各カテゴリの下にその子がある方法で選択する必要があります。写真から、次のようになります。

Sample Category 1
   Sample rule 1
Sample Category 2

ここから見つけたいくつかのクエリを試しましたが、どれもうまくいきませんでした。

これは私が最後に試したことです:

'SELECT *
FROM ' . RULES_TABLE . ' AS parent
    LEFT JOIN ' . RULES_TABLE . ' AS child 
    ON child.parent_id = parent.rule_id 
WHERE parent.parent_id = 0
     AND parent.public = 1
ORDER BY parent.cat_position, child.rule_position';

サンプル ルール 1のみが返されました。

アイデア?

4

2 に答える 2

2

このフィドルを試してくださいhttp://sqlfiddle.com/#!2/0a9c5/16、以下のSQLコード

SELECT c.rule_id, c.rule_title, GROUP_CONCAT(r.rule_title)
FROM RULES_TABLE AS c
LEFT JOIN RULES_TABLE AS r
    ON r.parent_id = c.rule_id
WHERE c.parent_id IS NULL AND c.public = 1
GROUP BY c.rule_id
ORDER BY c.cat_position, c.rule_position;

構文の強調表示を維持するために意図的にコードのphp化を省略しましたが、とにかく機能しないようです

許可されている最大group_concatサイズを超える場合は、サイズを増やすか、次のバージョンを使用して、phpでもう少し処理を行うことができます。

SELECT c.rule_id, c.rule_title, r.rule_title as r_rule_title
FROM RULES_TABLE AS c
LEFT JOIN RULES_TABLE AS r
    ON r.parent_id = c.rule_id
WHERE c.parent_id IS NULL AND c.public = 1
ORDER BY c.cat_position, c.rule_position;

また、phpでは、スケルトンコードのみが提供され、pdoを使用し、pdostatement varの名前が次のようになっていると仮定して、実際の値を入力します$query

$old_rule_id = null;
$rrt = array(); // will contain all r.rule_titles for a give c.rule_id
while( ($i = $query->fetch(PDO::FETCH_OBJ)) !== false ) {
    if( $old_rule_id != $i->rule_id ) {
        if( count($rrt) ) {
            echo ... all the data for previous rule from $rrt ...
            echo ... end of previous element ...
            $rrt = array(); // empty it to collect new data
        }
        echo ... start of current element use data from $i->rule_id and $i->rule_title ...
        $old_rule_id = $rule_id;
    }
    $rrt[] = $i->r_rule_title;
}
// the following is the same if from inside the while, minus reinitialization of $rrt;
if( count($rrt) ) {
    echo ... all the data for previous rule from $rrt ...
    echo ... end of previous element ...
}

...の間のものを有効なコードに置き換えます

于 2012-10-07T16:23:24.467 に答える
-1

FOR XML EXPLICIT を使用すると、階層リストを取得できます。

これを試して:

SELECT 
 1 Tag,
 null Parent,
 '' [root!1!name],
 null [category!2!id],
 null [category!2!name],
 null [rule!3!id],
 null [rule!3!name]

UNION ALL 

SELECT DISTINCT 
 2 Tag,
 1 Parent,
 null,
 rule_id [category!2!id],
 rule_title [category!2!name],
 null [rule!3!id],
 null [rule!3!name]
FROM rules
WHERE parent_id = 0 and rule_type = 'cat'

UNION ALL 

SELECT  
 3 Tag,
 2 Parent,
 null,
 parent_id [category!2!id],
 null [category!2!name],
 rule_id [rule!3!id],
 rule_title [rule!3!name]
FROM rules
WHERE parent_id > 0 and rule_type = 'rule'

FOR XML EXPLICIT

詳細については、http://msdn.microsoft.com/en-us/library/ms189068.aspxをご覧ください。

于 2012-10-07T16:35:30.917 に答える