从给定数据库表中构建导航数组的高效方法,查询建议

时间:2015-11-10 16:05:51

标签: php arrays sql-server performance navigation

我有下表“ProductCatalogCategories”

╔═══════════════════╤═════════════╤══════════════════╤══════════════════════╤═════════════╤══════╗
║ ProductCategoryID │ DisplayName │ ParentCategoryID │ PresentationSequence │ b_IsDeleted │ Code ║
╠═══════════════════╪═════════════╪══════════════════╪══════════════════════╪═════════════╪══════╣
║ 2                 │ Fruits      │                  │ 1                    │ 0           │      ║
╟───────────────────┼─────────────┼──────────────────┼──────────────────────┼─────────────┼──────╢
║ 4                 │ Banana      │ 2                │ 2                    │ 0           │      ║
╟───────────────────┼─────────────┼──────────────────┼──────────────────────┼─────────────┼──────╢
║ 6                 │ Apple       │ 2                │ 3                    │ 0           │      ║
╟───────────────────┼─────────────┼──────────────────┼──────────────────────┼─────────────┼──────╢
║ 8                 │ Cars        │                  │ 2                    │ 0           │      ║
╚═══════════════════╧═════════════╧══════════════════╧══════════════════════╧═════════════╧══════╝

该表由以下主要栏目组成:
ProductCategoryID用于标识类别,
DisplayName,
和ParentCategoryID来构建父=>儿童构建

我的目标是建立一个类似这样的数组:

$aim = [
    "c_2"=>[
        "Name"=>"Fruits",
        "Children"=>[
             "c_4"=>[
                 "Name"=>"Banana",
                 "Children"=>[]
             ],
             "c_6"=>[
                 "Name"=>"Apple",
                 "Children"=>[]
             ]
        ]
    ],
    "c_8"=>[
        "Name"=>"Cars",
        "Children"=>[]
    ]
]

这个构造是无限可扩展的,所以我想编写一个递归函数来获得这个构造,它的工作正常但性能不是很好:

$topLevel_q = sqlsrv_query($MSSQL, "SELECT ProductCategoryID,DisplayName,AccessGroupID FROM ProductCatalogCategories WHERE b_isDeleted = '0'  AND ParentCategoryID IS NULL AND NOT Code = 'CONTENT'  ORDER BY PresentationSequence ASC");
$topLevel = [];

$result = [];

while ($cat = sqlsrv_fetch_array($topLevel_q, SQLSRV_FETCH_ASSOC)) {
    $result["c_" . $cat["ProductCategoryID"]] = [
        "Name" => $cat["DisplayName"],
        "Children" => walkCats($cat["ProductCategoryID"], $MSSQL)
    ];
}

function walkCats($cat, $MSSQL) {
    $deeper = sqlsrv_query($MSSQL, "SELECT ProductCategoryID,DisplayName,AccessGroupID FROM ProductCatalogCategories WHERE b_isDeleted = '0'  AND ParentCategoryID='{$cat}' AND NOT Code = 'CONTENT'  ORDER BY PresentationSequence ASC");

    $next = [];

    while ($cat = sqlsrv_fetch_array($deeper, SQLSRV_FETCH_ASSOC)) {
        $next["c_" . $cat["ProductCategoryID"]] = [
            "Name" => $cat["DisplayName"],
            "Children" => walkCats($cat["ProductCategoryID"], $MSSQL)
        ];
    }

    return $next;
}

现在我的问题是,有更好的方法来获得构造吗? 我玩了一些连接,但我找不到我的结果与其他查询。

现在它的方式很容易就会有50个查询调用,只有3-4个类别,并且都有2-3个级别,应该有更好的查询来解决这个问题,但我仍然没有高级查询经验。

提前谢谢!

1 个答案:

答案 0 :(得分:0)

这应该有效!您也可以尝试使用SQL查询。

$topLevel_q = sqlsrv_query($MSSQL, "SELECT * FROM ProductCatalogCategories WHERE b_isDeleted = '0' AND NOT Code = 'CONTENT' ORDER BY ParentCategoryID DESC, PresentationSequence ASC");

$result = [];

while ($cat = sqlsrv_fetch_array($topLevel_q, SQLSRV_FETCH_ASSOC)) {
    $result["c_" . $cat["ProductCategoryID"]] = $cat;
}

foreach ($result as $key => &$categoryRow) {
    $parentId = ($categoryRow['ParentCategoryID'] > 0) ? $categoryRow['ParentCategoryID'] : 'root';
    if($parentId !== 'root')
        $result["c_" . $parentId]['Children'][$key] = $categoryRow;
    else
        $result[$parentId]['Children'][$key] = $categoryRow;

    if ($parentId !== 'root')
        unset($result[$key]);
}

if (!empty($result['root']['Children']) && $result['root']['Children'] && count($result['root']['Children']) > 1) {
    array_pop($result['root']['Children']);
}

$result = $result['root']['Children'];