SQL - 不同记录中的父 - 子关系

时间:2012-06-07 19:21:01

标签: sql parent-child

我已经获得了一个具有父子关系的SQL表,我希望以可读的格式呈现。

涉及的主要栏目是抽屉,文件夹,文件。每个抽屉可以有多个与之关联的文件夹,每个文件夹可以有多个与之关联的文档。但是,文件夹和文档未列在同一记录中。

此表包含项目类型,文件夹和文档都被视为项目。要关联它们,表格会将文件夹的项目编号分配给文档记录中的parentID。

例如:

DrawerID   ItemID    ParentID    Type    Name  
  1          1          0       Folder   Folder 1  
  1          2          0       Folder   Folder 2  
  1          3          0       Folder   Folder 3  
  1          4          0       Folder   Folder 4  
  1          5          1       Document Document A  
  1          6          1       Document Document B   
  1          7          1       Document Document C 
  1          8          2       Document Document A  
  1          9          3       Document Document A  
  1          10         3       Document Document B 

我正在寻找的是类似于此的输出:

Drawer 1
    Folder 1
        Document A
        Document B
        Document C
    Folder 2
        Document A
    Folder 3
        Document A
        Document B    

我坚持的部分是如何将ParentID绑定到ItemID。最好的方法是某种联盟吗?递归编程到新表?我不是一个SQL人员 - 我只是剪切和粘贴一些查询,所以请用一些小词:)

4 个答案:

答案 0 :(得分:0)

如果您只是深入两个级别,那么创建这样的数据可能是有意义的:

DrawerID    FolderID    ItemId    Description    ...

文件夹本身的项ID为null或零。

然后你可以查询:

SELECT * FROM table ORDER BY DrawerID, FolderID, ItemID

答案 1 :(得分:0)

标准SQL中没有递归。

但是,有一些模式可以解决您遇到的问题,其中之一是nested sets

答案 2 :(得分:0)

此查询应该可以在SQL Server上对您的数据进行测试。基本上它在查询中创建两个伪表来表示文件夹和文档实体,然后在父关系上连接在一起:

SELECT Folder.DrawerID, Folder.FolderId, Folder.FolderName, Doc.DocumentId, Doc.DocumentName
    FROM 

    (Select DrawerId, ItemId AS FolderId, ParentId, [Name] AS FolderName FROM Drawers WHERE [Type] ='Folder') Folder,

    (Select DrawerId, ItemId AS DocumentId, ParentId, [Name] AS DocumentName FROM Drawers  WHERE [Type] ='Document') Doc

    WHERE Doc.ParentId = Folder.FolderId
    ORDER BY DrawerId, FolderName, DocumentName

答案 3 :(得分:0)

如果您知道要处理多少级别,则可以使用自联接。在自联接中,您基本上假装同一个表是一个新表,并使用不同的名称对其进行别名(T2或其他)。这个例子可以帮助你入门:

顺便提一下,您的数据存在一个奇怪的问题,应该存在一个抽屉ID为0的单行,以便完成该概念。必须更改以下代码或修复错误

select 

T1.name,
T2.name,
T3.name //etc repeat as needed and below

from myTable T1

LEFT OUTER JOIN myTable T2 ON
  T2.ParentID= T1.ItemID

LEFT OUTER JOIN myTable T2 ON
  T2.ParentID= T3.ItemID

group by 1,2,3