MYSQL:选择父按字母顺序排序,按字母顺序排序

时间:2014-01-23 05:45:43

标签: php mysql database sorting

我已经制作了一个简单的表来理解亲子关系,但我似乎没有得到正确的结果。我想对它进行排序

  1. 首先按'名称'字段按字母顺序排列,只有那些没有父母的人(parent_id == 0)
  2. 但是,只要父项有子行,就应该在父项之后打印,也按名称的字母顺序排序。
  3. 示例表:

    =============================================== =============

    CREATE TABLE IF NOT EXISTS `test` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `parent_id` int(11) NOT NULL DEFAULT '0',
      `name` varchar(255) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=9 ;
    
    --
    -- Dumping data for table `test`
    --
    
    INSERT INTO `test` (`id`, `parent_id`, `name`) VALUES
    (1, 4, 'Zorg'),
    (2, 0, 'Woordolack'),
    (3, 4, 'Akriller'),
    (4, 0, 'Metabrusher'),
    (5, 2, 'Intersplitter'),
    (6, 0, 'Beaverbrain'),
    (7, 4, 'Torgeoruos'),
    (8, 2, 'Deptezaurus');
    

    =============================================== =============

    以下是我想使用PHP输出到Web浏览器的内容:

     Beaverbrain
     Metabrusher
     -> Akriller
     -> Torgeoruos
     -> Zorg
     Woordolack
     -> Deptezaurus
     -> Intersplitter
    

    =============================================== =============

    我应该说这是一个示例表来展示这个想法,所以可以通过任何方式修改它以获得正确的结果。

4 个答案:

答案 0 :(得分:3)

您可以尝试此查询

SELECT IF(child = '',parent,CONCAT('->',child)) as value 
FROM
    (SELECT parent.name as parent,child.name as child
     FROM test parent 
       INNER JOIN 
       (SELECT id,parent_id,name FROM test 
        UNION 
        SELECT null,id,'' FROM test
        WHERE parent_id = 0)child
     WHERE parent.parent_id = 0
     AND child.parent_id = parent.id
     ORDER BY parent,child
     )parent_child

sqlFiddle

查询的作用是INNER JOIN test with test并找出哪个是父级和子级。内部UNION SELECT null,id,'' FROM test WHERE parent_id = 0创建一个空子(ren)用于显示目的。然后,外部SELECT看到孩子是否''它打印出父母,否则它在孩子面前结束->。所以你得到的结果就像你想要的那样。

以下版本可能会快一点。因为我们只是使用NULL子节点创建父节点而不是使用子节点作为INNER JOIN的一部分(上图)。

SELECT IF(child IS NULL,parent,CONCAT('->',child)) as value 
FROM
 (SELECT parent.name as parent,child.name as child
    FROM test parent 
   INNER JOIN test child ON child.parent_id = parent.id
   WHERE parent.parent_id = 0
  UNION
  SELECT test.name as parent,NULL as child    #This creates a NULL child row
    FROM test WHERE test.parent_id = 0        #for parent display purpose
  ORDER BY parent,child
 )parent_child

sqlFiddle

然而,我会在PHP中使用以下查询,检查isParent标志是1还是0,然后显示相应的字段。

SELECT 0 as isParent,parent.name as parent,child.name as child,
       parent.id as parentId,child.id as childId
  FROM test parent 
 INNER JOIN test child ON child.parent_id = parent.id
 WHERE parent.parent_id = 0
UNION
SELECT 1 as isParent,test.name as parent,NULL as child,
       test.id as parentId,NULL as childId
  FROM test WHERE test.parent_id = 0       
ORDER BY parent,child

sqlFiddle

答案 1 :(得分:0)

在管理分层数据时,您可以使用简单的PHP递归函数,

 function DisplayTree( $parent , $depth)     {                                                                                                    
    $sql = $this->db->query("SELECT id,name FROM '$table' WHERE parent_id = '$parent'");

      foreach($sql->result() as $field ) {  
        print "<fieldset style=\"margin-left:$depth%; width:300px\">";  
            print $field->name;
        print "</fieldset>";

        $this->DisplayTree( $field->code , $depth+8 );           
     }  

   }  

答案 2 :(得分:0)

在PHP中使用几个简单的查询,

    $r1 = $db->query("select * from test where parent_id = 0 order by name asc") or die('err in q1');
    while($arr1 = $r1->fetch_assoc()){
            $parent = $arr1['name'];
            $parent_id = $arr1['id'];
            echo $parent
            $r2 = $db->query("select * from test where parent_id = $parent order by name asc") or die('err in q2');
            while($arr2 = $r2->fetch_assoc()){
                 $child = $arr2['name'];
                 echo $child."<br />";
            }
    }

答案 3 :(得分:0)

试试这个解决方案:

SELECT
    A.id,
    A.name
FROM 
    `test` AS A LEFT JOIN `test` AS B ON A.`parent_id` = B.`id`
GROUP BY
    A.`id`
ORDER BY
    IFNULL(B.`name`, A.`name`), 
    COALESCE(A.`parent_id`, A.`id`), 
    A.`parent_id` != 0, 
    A.`name`;