从多个MySQL表构建无序列表

时间:2014-11-07 08:39:24

标签: php html mysql web html-lists

我正在尝试构建一个填充了类别,子类别和第三类的菜单,这些类别存储在数据库中的三个单独的表中,如下所示:

TABLE A
------------------------
| ID | name            |
| 1  | Category 1      |
| 2  | Category 2      |
------------------------

TABLE B
------------------------------------
| ID | Parent_ID | name_b          |
| 1  |     1     | Subcategory 1   |
| 2  |     1     | Subcategory 2   |
| 3  |     2     | Subcategory 3   |
------------------------------------

TABLE C
--------------------------------------
| ID | Parent_ID | name_c             |
| 1  |     1     | Tertiarycategory 1 |
| 2  |     2     | Tertiarycategory 2 |
| 3  |     2     | Tertiarycategory 3 |
| 4  |     3     | Tertiarycategory 4 |
--------------------------------------

这些应该在一个看起来像

的无序列表中返回
  • 第1类
    • 子类别1
      • Tertiarycategory 1
    • 子类别2
      • Tertiarycategory 2
      • Tertiarycategory 3
  • 第2类
    • 子类别3
      • Tertiarycategory 4

我一直在谷歌搜索几天,现在尝试不同的东西,但似乎无法让它工作,所以非常感谢它,如果有人可以破解它:)

尝试获得第一级和第二级(没有列表,只是正常的回声,而我得到的查询正确)但它根本不起作用...

    $query_select = "SELECT * FROM table_a";
$result_select = mysqli_query($link, $query_select) or die(mysql_error());
$rows = array();
while($menurow = mysqli_fetch_array($result_select))
$menurows[] = $menurow;
foreach($menurows as $menurow){ 
$ename = stripslashes($menurow['name']);
$eid = $menurow['id'];
echo $ename . '<br/>';
        $query_select2 = "SELECT * FROM table_b WHERE parent_id = '$eid'";
        $result_select2 = mysqli_query($link, $query_select2) or die(mysql_error());
        $rows2 = array();
        while($menurow2 = mysqli_fetch_array($result_select2))
        $menurows2[] = $menurow2;
        foreach($menurows2 as $menurow2){ 
        $ename2 = stripslashes($menurow2['name_b']);
        $eid2 = $menurow2['id'];
        echo $ename2 . '<br/>';

}

}

3 个答案:

答案 0 :(得分:1)

所有查询都在一个维度中返回数据。但你可以有这样的解决方法:

SELECT x.level,x.id,x.name
FROM
(
  SELECT 1 as level, id as id, name as name
    , id as id_1,-1 as id_2, -1 as id_3
    FROM table_a
    WHERE 1
  UNION
  SELECT 2 as level, id as id, name_b as name
    , Parent_ID as id_1,id as id_2, -1 as id_3
    FROM table_b
    WHERE 1
  UNION
  SELECT 3 as level, c.id as id, c.name_c as name
    , b.Parent_ID as id_1,b.id as id_2, c.id as id_3
    FROM table_c c LEFT JOIN table_b b ON c.Parent_ID=b.id
    WHERE 1
) x
WHERE 1
ORDER BY id_1,id_2,id_3

应返回

Level | Name
1       Category 1
2       Subcategory 1
3       Tertiarycategory 1
2       Subcategory 2
3       Tertiarycategory 2
3       Tertiarycategory 3
1       Category 2
2       Subcategory 3
3       Tertiarycategory 4

和PHP代码是:

$r = $db->query($query);
$level = 0;
while($x=mysql_fetch_object($r))
{
   while($level < $x->level)
   {
      echo '<ul>';
      $level++;
   }
   while($level > $x->level)
   {
      echo '</ul>';
      $level--;
   }
   echo '<li>'$x->ID.'#'.$x->name;
} 
while($level-- > 0)
   echo '</ul>';

编辑或者,不要将构建工作留给MySQL,而是让它在PHP内部完成

$r1 = $db->query("SELECT * FROM table_a order by ID");
$r2 = $db->query("SELECT * FROM table_b order by Parent_ID");
$r3 = $db->query("SELECT table_c.* 
                  FROM table_c
                  LEFT JOIN table_b ON table_c.Parent_ID=table_b.ID
                  order by table_b.Parent_ID");

$e1 = mysql_fetch_object($r1);
$e2 = mysql_fetch_object($r2);
$e3 = mysql_fetch_object($r3);

echo "<ul>";
while($e1)
{
   echo "<li>".htmlentities($e1->name);
   if($e2 && $e2->Parent_ID==$e1->ID)
   {
      echo "<ul>";
      while($e2 && $e2->Parent_ID==$e1->ID)
      {
         echo "<li>".htmlentities($e2->name_b);
         if($e3 && $e3->Parent_ID==$e2->ID)
         {
            echo "<ul>";
            while($e3 && $e3->Parent_ID==$e2->ID)
            {
               echo "<li>".htmlentities($e3->name_3);
               $e3 = mysql_fetch_object($r3);
            }
            echo "</ul>";
         }
         $e2 = mysql_fetch_object($r2);
      }
      echo "</ul>";
   }
   $e1 = mysql_fetch_object($r1);
}
echo "</ul>";

答案 1 :(得分:1)

我只是使用一个简单的连接来获取所有父/子关系,并在代码更改时对代码中顶级父项的输出进行排序(这在php中很容易)。

SELECT name, name_b, name_c
FROM A
LEFT OUTER JOIN B
ON A.ID = B.Parent_ID
LEFT OUTER JOIN C
ON B.ID = C.Parent_ID
ORDER BY A.ID, B.ID, C.ID

修改

PHP脚本,用于从表中获取详细信息并构建无序列表。

这使用一个小类输出每个无序列表,在析构函数中关闭它。然后,它为每个无序列表级别创建此类的实例。

<?php

#------ database connections -------
define('MYSQLHOST','localhost');
define('MYSQLUSER','root');
define('MYSQLPASS','');
define('MYSQLDATABASE','tests');

$link = mysqli_connect(MYSQLHOST, MYSQLUSER, MYSQLPASS, MYSQLDATABASE);

$prev_name = '';
$prev_name_b = '';
$prev_name_c = '';

$query_select = "SELECT name, name_b, name_c
                FROM A
                LEFT OUTER JOIN B
                ON A.ID = B.Parent_ID
                LEFT OUTER JOIN C
                ON B.ID = C.Parent_ID
                ORDER BY A.ID, B.ID, C.ID";

$result_select = mysqli_query($link, $query_select) or die(mysql_error());
$rows = array();
while($menurow = mysqli_fetch_array($result_select))
{
    if ($menurow['name'] != $prev_name)
    {
        if (isset($name_c_object)) unset($name_c_object);
        if (isset($name_b_object)) unset($name_b_object);
        if (isset($name_object)) unset($name_object);
        $name_object = new ul(1);
        $prev_name = $menurow['name'];
        $name_object->li($prev_name);
    }
    if ($menurow['name_b'] != $prev_name_b)
    {
        if (isset($name_c_object)) unset($name_c_object);
        if (isset($name_b_object)) unset($name_b_object);
        $name_b_object = new ul(3);
        $prev_name_b = $menurow['name_b'];
        $name_b_object->li($prev_name_b);
        if (isset($name_c_object)) unset($name_c_object);
        $name_c_object = new ul(5);
    }
    $name_c_object->li($menurow['name_c']);
}

if (isset($name_c_object)) unset($name_c_object);
if (isset($name_b_object)) unset($name_b_object);
if (isset($name_object)) unset($name_object);

class ul
{
    private $out_li = false;
    private $num_tab = 0;
    public function __CONSTRUCT($num_tab)
    {
        $this->num_tab = $num_tab;
        echo str_repeat("\t", $this->num_tab)."<ul>\r\n";
    }
    public function __DESTRUCT()
    {
        if ($this->out_li) echo str_repeat("\t", $this->num_tab)."\t</li>\r\n";
        echo str_repeat("\t", $this->num_tab)."</ul>\r\n";
    }
    public function li($li)
    {
        if ($this->out_li) echo str_repeat("\t", $this->num_tab)."\t</li>\r\n";
        echo str_repeat("\t", $this->num_tab)."\t<li>\r\n";
        echo str_repeat("\t", $this->num_tab)."\t\t$li\r\n";
        $this->out_li = true;
    }
}

再次编辑

我有一个重新思考并绕过它: -

<?php

#------ database connections -------
define('MYSQLHOST','localhost');
define('MYSQLUSER','root');
define('MYSQLPASS','');
define('MYSQLDATABASE','tests');

$link = mysqli_connect(MYSQLHOST, MYSQLUSER, MYSQLPASS, MYSQLDATABASE);

$prev_id_a = 0;
$prev_id_b = 0;
$prev_id_c = 0;

$query_select = "SELECT name, name_b, name_c, A.ID AS aid, B.ID AS bid, C.ID AS cid
                FROM A
                LEFT OUTER JOIN B
                ON A.ID = B.Parent_ID
                LEFT OUTER JOIN C
                ON B.ID = C.Parent_ID
                ORDER BY A.ID, B.ID, C.ID";

$result_select = mysqli_query($link, $query_select) or die(mysql_error());
$rows = array();

$name_a_object = new ul(0);

while($menurow = mysqli_fetch_array($result_select))
{
    if ($menurow['aid'] != $prev_id_a)
    {
        if (isset($name_c_object)) unset($name_c_object);
        if (isset($name_b_object)) unset($name_b_object);
        $name_a_object->li($menurow['name']);
        $name_b_object = new ul(2);
        $prev_id_a = $menurow['aid'];
    }
    if ($menurow['bid'] != $prev_id_b)
    {
        if (isset($name_c_object)) unset($name_c_object);
        $name_b_object->li($menurow['name_b']);
        $name_c_object = new ul(4);
        $prev_id_b = $menurow['bid'];
    }
    $name_c_object->li($menurow['name_c']);
}

if (isset($name_c_object)) unset($name_c_object);
if (isset($name_b_object)) unset($name_b_object);
if (isset($name_a_object)) unset($name_a_object);

class ul
{
    private $num_tab = 0;
    private $li_output = false;
    public function __CONSTRUCT($num_tab, $li=null)
    {
        $this->num_tab = $num_tab;
        echo str_repeat("\t", $this->num_tab)."<ul>\r\n";
        if ($li != null)
        {
            echo str_repeat("\t", $this->num_tab)."\t<li>\r\n";
            echo str_repeat("\t", $this->num_tab)."\t\t$li\r\n";
        }
    }
    public function __DESTRUCT()
    {
        if ($this->li_output)
        {
            echo str_repeat("\t", $this->num_tab)."\t</li>\r\n";
        }
        echo str_repeat("\t", $this->num_tab)."</ul>\r\n";
    }
    public function li($li)
    {
        if ($this->li_output)
        {
            echo str_repeat("\t", $this->num_tab)."\t</li>\r\n";
        }
        echo str_repeat("\t", $this->num_tab)."\t<li>\r\n";
        echo str_repeat("\t", $this->num_tab)."\t\t$li\r\n";
        $this->li_output = true;
    }
}

答案 2 :(得分:0)

这是当前的代码,但不返回任何结果。

<?php
$host = "localhost"; //server
$db = "xx"; //database name
$user = "xx"; //dabases user name
$pwd = "xx"; //password

//connecting to server and creating link to database
$dblink = mysqli_connect($host, $user, $pwd, $db);

$r1 = $dblink->query("SELECT * FROM auction_a_categories order by ID");
$r2 = $dblink->query("SELECT * FROM auction_b_categories order by Parent_ID");
$r3 = $dblink->query("SELECT auction_c_categories.* 
                  FROM auction_c_categories
                  LEFT JOIN auction_b_categories ON auction_c_categories.Parent_ID=auction_b_categories.ID
                  order by auction_b_categories.Parent_ID");

$e1 = mysql_fetch_object($r1);
$e2 = mysql_fetch_object($r2);
$e3 = mysql_fetch_object($r3);

echo "<ul>";
while($e1)
{
   echo "<li>".htmlentities($e1->name);
   if($e2 && $e2->Parent_ID==$e1->ID)
   {
      echo "<ul>";
      while($e2 && $e2->Parent_ID==$e1->ID)
      {
         echo "<li>".htmlentities($e2->name_b);
         if($e3 && $e3->Parent_ID==$e2->ID)
         {
            echo "<ul>";
            while($e3 && $e3->Parent_ID==$e2->ID)
            {
               echo "<li>".htmlentities($e3->name_3);
               $e3 = mysql_fetch_object($r3);
            }
            echo "</ul>";
         }
         $e2 = mysql_fetch_object($r2);
      }
      echo "</ul>";
   }
   $e1 = mysql_fetch_object($r1);
}
echo "</ul>";

?>