我正在尝试使用asp.net中的SQL数据源创建分层菜单。我在订购桌面时遇到了麻烦,因此我可以轻松地在asp.net中创建菜单。如果有人有任何想法,可能有更好的方法来做到这一点......
我目前有一个看起来像这样的表(组成样本数据),根目录只有文件夹,只有文件夹可以有文件夹ID:
+-------------------+---------------------+-----------+-----------+
| Name_FolderorItem | Parent_Folder | Id_Folder | Menuplace |
+-------------------+---------------------+-----------+-----------+
| c FOLDER | ROOT | c_FOLDER | 1 |
| d FOLDER | j_FOLDER | d_FOLDER | 2 |
| a FOLDER | ROOT | a_FOLDER | 1 |
| j FOLDER | ROOT | j_FOLDER | 1 |
| f FOLDER | ROOT | f_FOLDER | 1 |
| r FOLDER | f_FOLDER | r_FOLDER | 2 |
| i FOLDER | d_FOLDER | i_FOLDER | 3 |
| a ITEM | j_FOLDER | | 2 |
| d ITEM | c_FOLDER | | 2 |
| z ITEM | f_FOLDER | | 2 |
| r ITEM | d_FOLDER | | 3 |
+-------------------+---------------------+-----------+-----------+
我在想,如果我命令它在第一级按字母顺序排列,则在每个更深层次上按字母顺序排列:
+-------------------+---------------------+-----------+-----------+
| Name_FolderorItem | Parent_Folder | Id_Folder | Menuplace |
+-------------------+---------------------+-----------+-----------+
| a FOLDER | ROOT | a_FOLDER | 1 |
| c FOLDER | ROOT | c_FOLDER | 1 |
| d ITEM | c_FOLDER | | 2 |
| f FOLDER | ROOT | f_FOLDER | 1 |
| r FOLDER | f_FOLDER | r_FOLDER | 2 |
| z ITEM | f_FOLDER | | 2 |
| j FOLDER | ROOT | j_FOLDER | 1 |
| a ITEM | j_FOLDER | | 2 |
| d FOLDER | j_FOLDER | d_FOLDER | 2 |
| i FOLDER | d_FOLDER | i_FOLDER | 3 |
| r ITEM | d_FOLDER | | 3 |
+-------------------+---------------------+-----------+-----------+
然后我可以使用listview来获取这个菜单结构:
a FOLDER
c FOLDER
- d ITEM
f FOLDER
- r FOLDER (r FOLDER is located in f folder)
- z ITEM
j FOLDER
- a item
- d FOLDER
- - i FOLDER
- - r ITEM
我似乎无法找出所需的SQL来获取文件夹,然后优先考虑其中的内容而不是该级别上的其他文件夹/项目。
如果你对允许这种排序的SQL语句有任何想法,我将不胜感激,提前谢谢
编辑: 这是我正在使用的查询,感谢您的帮助
SELECT *
FROM table
START WITH Parent_Folder LIKE 'ROOT'
CONNECT BY PRIOR Id_Folder LIKE Parent_folder;
答案 0 :(得分:1)
这基本上是在数据库中存储 有序树 的问题。我过去曾尝试过一些方法,并会推荐这个方法:
-----------------------------------
| NodeID | ParentID | Order |
-----------------------------------
| 1 | -1 | 1 |
| 2 | 1 | 1 |
| 3 | 1 | 2 |
| 4 | 3 | 1 |
-----------------------------------
GIST是每一行对应树中的一个节点(或您的案例中的菜单项),它有一个指向父节点的parentID。根节点要么为null,要么-1具有其parentID,因为它没有。现在,要获取直接位于根目录下的所有节点,您可以使用
SELECT * FROM table WHERE ParentID = -1 ORDER BY [Order]
[Order]告诉您如何直接在特定父节点下订购节点。 (好吧,使用SQL关键字命名列不太好,但暂时不要忘记)。所以在我的例子中你可以看到“2”和“3”都在根目录下,但“2”首先出现。要直接选择“3”下的节点(换句话说是其子节点),您可以使用
SELECT * FROM table WHERE ParentID = 3 ORDER BY [Order]
这种方法的优点是可以轻松查询菜单。缺点是更新时,必须确保共享相同ParentID的节点(换句话说,在同一父节点下)不共享名称[Order]。
替代方法
另一种方法是将树存储为链接列表:
-----------------------------------
|NodeID | ParentID | PrevID | (optionally you can store NextID as well)
-----------------------------------
| 1 | -1 | -1 |
| 2 | 1 | -1 |
| 3 | 1 | 2 |
| 4 | 3 | -1 |
-----------------------------------
如果您的树非常大并且需要快速浏览兄弟节点,这种方法可以提供更好的性能。