从像这样的表中检索层次结构

时间:2013-05-06 03:39:53

标签: php mysql sql hierarchical-data

我正在使用MySql和PHP,并将我的所有数据都放在这样的表中:

"id"    "name"         "description"               "level"  "parent"    "country"   "maxLevel"
"1"     "Kitchenware"   "Kitchenware description"   "1"       "0"         "US"        "0"
"2"     "Knives"        "All our knives"            "2"       "1"         "US"        "0"
"3"     "Butter Knives" "All Butter Knives"         "3"       "2"         "US"        "0"
"4"     "Cut em all"    "Cut em all"                "4"       "3"         "US"        "0"
"5"     "Cull em all"   "Cull em all"               "4"       "3"         "US"        "0"
"6"     "Smear em all"  "Smear em all"              "4"       "3"         "US"        "0"
"7"     "Meat Knives"   "All Meat Knives"           "3"       "2"         "US"        "0"
"8"     "Cut em meat"   "Cut em meat"               "4"       "7"         "US"        "0"
"9"     "Cull em meat"  "Cull em meat"              "4"       "7"         "US"        "0"
"10"    "Smear em meat" "Smear em meat"             "4"       "7"         "US"        "0"

由此,如果我有例如:id = 10,sql将如何显示项目的层次结构?

因此,对于id = 10,层次结构将是:

Kitchenware > Knives > Meat Knives > Smear em meat

对于id = 7,hierrchy将是:

Kitchenware > Knives > Meat Knives

对于id = 4,层次结构将是

Kitchenware > Knives > Butter Knives > Cut em all

等等。知道如何构造sql来实现这个目标吗?

2 个答案:

答案 0 :(得分:4)

尝试此存储过程

CREATE PROCEDURE updatePath(in itemId int)
BEGIN
    DECLARE cnt int default 0;
    CREATE temporary table tmpTable 
    (
       `id` int, `name` varchar(15), `parent` int, path varchar(500)  
     )engine=memory select id, name, parent, name AS 'Path' from tbl where id = itemId;
    select parent into cnt from tmpTable;

    while cnt <> 0 do
       Update tmpTable tt, tbl t set tt.parent = t.parent, 
              tt.path = concat(t.name, ' > ', tt.path)
       WHERE tt.parent = t.id;
       select parent into cnt from tmpTable;
    end while;
    select * from tmpTable;
    drop table tmpTable;
END//

查询1

call updatePath(10)

SQL FIDDLE

| ID |            NAME | PARENT |                                                       PATH |
----------------------------------------------------------------------------------------------
| 10 | "Smear em meat" |      0 | "Kitchenware" > "Knives" > "Meat Knives" > "Smear em meat" |

希望这有帮助

答案 1 :(得分:3)

试试这个:

我会设置一个这样的SQL表:

CREATE TABLE `table` (
    `id` int(11),
    `name` varchar(32),
    `description` varchar(32),
    `level` int(11),
    `parent` int(11),
    `country` varchar(32),
    `maxLevel` int(11)
);

以下是要插入的测试数据:

INSERT INTO `table` VALUES
("1",     "Kitchenware",   "Kitchenware description",   "1",       "0",         "US",        "0"),
("2",     "Knives",        "All our knives",            "2",       "1",         "US",        "0"),
("3",     "Butter Knives", "All Butter Knives",         "3",       "2",         "US",        "0"),
("4",     "Cut em all",    "Cut em all",                "4",       "3",         "US",        "0"),
("5",     "Cull em all",   "Cull em all",               "4",       "3",         "US",        "0"),
("6",     "Smear em all",  "Smear em all",              "4",       "3",         "US",        "0"),
("7",     "Meat Knives",   "All Meat Knives",           "3",       "2",         "US",        "0"),
("8",     "Cut em meat",   "Cut em meat",               "4",       "7",         "US",        "0"),
("9",     "Cull em meat",  "Cull em meat",              "4",       "7",         "US",        "0"),
("10",    "Smear em meat", "Smear em meat",             "4",       "7",         "US",        "0");

最后,这是要测试的代码:

<?php
$mysqli=new Mysqli("127.0.0.1","root","DATABASE_PASSWORD","DATABASE_NAME");

function getHierarchy($id) {
    global $mysqli;

    $final="";

    $query="SELECT `name`,`parent` FROM `table` WHERE `id`=";
    $result=$mysqli->query($query.$id);
    $result=$result->fetch_assoc();

    while($result['parent']!=0) {
        $result=$mysqli->query($query.$id);
        $result=$result->fetch_assoc();
        $id=$result['parent'];
        $final=$result["name"]." > ".$final;
    }

    $final=substr($final,0,-3);
    return $final;
}

echo getHierarchy(10)."<br>\n";
echo getHierarchy(7)."<br>\n";
echo getHierarchy(4)."<br>\n";

$mysqli->close();
?>

打印出来:

Kitchenware > Knives > Meat Knives > Smear em meat
Kitchenware > Knives > Meat Knives
Kitchenware > Knives > Butter Knives > Cut em all