我陷入了这个逻辑问题,我不知道如何继续。
我有两列:ID和FOLDERID。由于文件夹也可以是子文件夹,我想通过首先选择没有folderid(根文件夹)的文件夹,然后选择它们的子文件夹并打开来命令我的结果。所以这样我就不会遇到像“文件夹 X 不存在”这样的问题。
在这个例子中,我无法通过FOLDERID ASC和/或ID ASC的简单排序获得我所需要的。
正确的结果是第3个:
我在同一张表中尝试了多种ORDER BY和JOIN / LEFT JOIN的方法,但无法弄清楚我是如何做到的。
有什么想法吗?
答案 0 :(得分:2)
您可以对CASE
使用ORDER
语句,对于您的示例,这可行,但听起来您可能在递归层次结构之后,语法因RDBMS而异:
ORDER BY CASE WHEN FolderID = 0 THEN 0 ELSE 1 END, ID
答案 1 :(得分:2)
如果您的dbms支持此操作,您可以选择分层查询。在oracle语法中:
select id
, name
, folderid
, sys_connect_by_path ( name, '/' ) path
from table t
connect by prior id = folderid
start with folderid = 0
order by path
;
答案 2 :(得分:1)
基于 collapsar 响应,我找到了一个解决我问题的Oracle CONNECT BY等价物。
WITH n([ID], [NAME], [OWNER], [FOLDERID]) AS
(SELECT [ID], [NAME], [OWNER], [FOLDERID]
FROM [RM_REPORTS_FOLDERS]
WHERE [FOLDERID] = 0
UNION ALL
SELECT nplus1.[ID], nplus1.[NAME], nplus1.[OWNER], nplus1.[FOLDERID]
FROM [RM_REPORTS_FOLDERS] as nplus1, n
WHERE n.[ID] = nplus1.[FOLDERID])
SELECT [ID], [NAME], [OWNER], [FOLDERID] FROM n
答案 3 :(得分:1)
使用简单的递归查询,您可以获得这些结果。
;WITH CTE
AS (SELECT *,
1 RN
FROM TABLE1
WHERE FOLDERID = 0
UNION ALL
SELECT T1.*,
T2.RN + 1
FROM TABLE1 T1
INNER JOIN CTE T2
ON T1.FOLDERID = T2.ID)
SELECT [ID],
[NAME],
[FOLDERID]
FROM CTE
ORDER BY RN
使用此查询,您还可以处理多个子文件夹。
查看SQL Fiddle上的工作示例 如果您想要了解有关递归查询的详细信息,请查看this blog。