排序选择逻辑问题(SQL)
我被困在这个逻辑问题上,不知道如何继续 我有两列:ID和FOLDERID。由于文件夹也可以是子文件夹,因此我想先选择没有folderid的文件夹(根文件夹),然后选择它们的子文件夹,然后再选择其他文件夹,以对结果进行排序。这样我就不会有任何问题,比如“文件夹X不存在” 在这个例子中,我无法通过FOLDERID ASC和/或ID ASC简单地排序来获得我需要的东西 正确的结果是第三个:排序选择逻辑问题(SQL),sql,sql-server,logic,Sql,Sql Server,Logic,我被困在这个逻辑问题上,不知道如何继续 我有两列:ID和FOLDERID。由于文件夹也可以是子文件夹,因此我想先选择没有folderid的文件夹(根文件夹),然后选择它们的子文件夹,然后再选择其他文件夹,以对结果进行排序。这样我就不会有任何问题,比如“文件夹X不存在” 在这个例子中,我无法通过FOLDERID ASC和/或ID ASC简单地排序来获得我需要的东西 正确的结果是第三个: 首先,我得到ID为2的“Teste”文件夹,因为它有folderid 0=root one 现在我想要“Con
有什么想法吗?您可以使用
CASE
语句来排序
,对于您的示例来说,这是可行的,但听起来您可能需要一个递归继承权,其语法会因RDBMS而异:
ORDER BY CASE WHEN FolderID = 0 THEN 0 ELSE 1 END, ID
您可以使用
CASE
语句来排序
,对于您的示例来说,这是可行的,但听起来您可能需要一个递归继承权,其语法会因RDBMS而异:
ORDER BY CASE WHEN FolderID = 0 THEN 0 ELSE 1 END, ID
如果您的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
;
如果您的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
;
根据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
根据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
使用简单的递归查询可以得到这些结果
;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
使用此查询还可以处理多个子文件夹
请看上的工作示例。如果您想了解有关递归查询的详细信息,请查看。使用简单的递归查询可以获得这些结果
;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表中没有隐式顺序(例如,按创建日期或诸如此类),您使用的是什么数据库?如果我理解正确,是否要像在树中一样对文件夹进行排序(深度优先搜索)?如果是这样的话,这就涉及递归,而SQL不适合这种情况。@marc_s,我所说的“创建日期”是指注册表在表中写入的顺序,对不起。@GordonLinoff,我使用的是SQL SERVER。如果您没有显式指定一个order by
,那么顺序是未定义的-没有隐式顺序(例如,通过创建日期或类似的方式)在SQL表中,您使用的是什么数据库?如果我理解正确,您希望像在树中一样对文件夹进行排序(深度优先搜索)?如果是这样,这涉及递归,而SQL并没有什么好处。@marc_,通过“创建日期”我的意思是注册表写入表中的顺序,对不起。@GordonLinoff,我使用的是SQL SERVER。不知道我们可以使用CASE-in-order-BY。我使用的是SQL SERVER的精简版本,我认为它是有效的。谢谢!但我需要问你是否可以解释order-BY在这段代码中的作用。当我们使用order-BY 0时,order-BY 1可以它不是按列索引排序吗?或者case语句的结果使用了另一种我不知道的方法?上面case语句的输出是每行0和1的数值,如果你说orderby1
,你就会使用列索引。如果你把case
语句放在SELECT中,你会这样想
您将为每一行获取一个值,然后您可以按该值排序。将其按顺序排序可以避免返回其输出。当子文件夹ID大于其父文件夹ID时,这将无法正常工作。的确,它适用于示例数据,但似乎最终需要递归a方法或类似方法。不知道我们可以使用CASE-in-ORDER-BY。我使用的是SQL SERVER的精简版本,我认为它有效。谢谢!但我需要问你是否可以解释一下ORDER-BY在这段代码中的作用。当我们使用ORDER-BY 0、ORDER-BY 1时,它不是按列索引排序吗?或者CASE语句的结果是按我不知道的另一种方法是什么?上面case语句的输出是每行0和1的数值,如果你说orderby1
,你就使用列索引。这样想吧,如果你把case
语句放在SELECT
中,你就会得到每行的值,然后你就可以按该值排序。Putt只需按顺序
,即可避免返回其输出。当子文件夹ID大于其父ID时,这将无法正常工作。非常正确,它适用于示例数据,但似乎最终需要递归方法或类似方法。这对我帮助很大。我正在使用SQL SERVER并发现了一些问题ng相当于Oracle的CONNECT BY。这符合我的需要:-)这对我帮助很大。我正在使用SQL SERVER,发现了与Oracle的CONNECT BY相当的东西。这符合我的需要:-)这个查询不能保证顺序。在测试中起作用的可能在生产中不起作用。在cte中添加一个深度递增器,并将其用于订购。您的意思是像Gidil response?我会尽力的。这个问题不能保证秩序。在测试中起作用的可能在生产中不起作用。在cte中添加一个深度递增器,并将其用于订购。您的意思是像Gidil response?我会尽力的。