排序选择逻辑问题(SQL)

排序选择逻辑问题(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

我被困在这个逻辑问题上,不知道如何继续

我有两列:ID和FOLDERID。由于文件夹也可以是子文件夹,因此我想先选择没有folderid的文件夹(根文件夹),然后选择它们的子文件夹,然后再选择其他文件夹,以对结果进行排序。这样我就不会有任何问题,比如“文件夹X不存在”

在这个例子中,我无法通过FOLDERID ASC和/或ID ASC简单地排序来获得我需要的东西

正确的结果是第三个:

  • 首先,我得到ID为2的“Teste”文件夹,因为它有folderid 0=root one
  • 现在我想要“Controladoria”文件夹,因为文件夹ID是2,所以需要首先创建文件夹ID 2(Teste)
  • “PCP”文件夹,需要id为1的文件夹(Controladoria)
  • “Pasta1”文件夹,需要id为3的文件夹(PCP)
  • 不停地
  • 我在同一个表中尝试了多种使用多个ORDER BY和JOIN/LEFT JOIN的方法,但我不知道如何做到这一点


    有什么想法吗?

    您可以使用
    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?我会尽力的。