选择并列出子项和父项

时间:2012-10-07 16:07:02

标签: php mysql sql select

我需要针对以下COMPLEX任务的SQL查询...

我需要从名为parent_id的列中进行选择。如果parent_id的行为0,则表示它是一个类别(它还有type列,其中cat表示类别),如果一行有{1}或更多这意味着它是一个规则。规则的parent_id是类别的parent_id

包含一些数据的表结构: phpMyAdmin table data

我需要以某种方式选择,即每个类别,其下有子项。从图片中我们可以得到这个:

rule_id

我尝试了一些我从这里找到的查询,但都没有用。

这是我上次尝试的内容:

Sample Category 1
   Sample rule 1
Sample Category 2

它仅返回示例规则1

想法?

2 个答案:

答案 0 :(得分: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 ...
}

用有效代码替换......之间的东西

答案 1 :(得分:-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