SQL Server:与多级或树节点连接

时间:2014-07-13 12:51:53

标签: sql sql-server select sql-server-2012

我在SQL Server 2012中有这两个表:

  1. 在此表中,我有类别和子类别

    CREATE TABLE [dbo].[Categories](
        [Id] [int] IDENTITY(1,1) NOT NULL,
        [ParentCategoryId] [int] NULL,
        [CategoryName] [nvarchar](100) NULL,
        [Slug] [nvarchar](150) NULL
    ) ON [PRIMARY]
    
  2. 此表包含照片项目

    CREATE TABLE [dbo].[Photos](
        [Id] [int] IDENTITY(1,1) NOT NULL,
        [CategoryId] [int] NULL,
        [FileName] [nvarchar](100) NULL,
        [Slug] [nvarchar](150) NULL
    ) ON [PRIMARY]
    
  3. 我想在SELECT表上创建一个SQL Photos,它返回Slug,它是照片项目的URL(不是实际图像)和类别slug。< / p>

    我需要来自DB的这些信息:

    /类别的蛞蝓/子类别段塞/光蛞蝓

    我有这个SELECT只返回类别

    的一个级别/节点的slug
    SELECT * 
    FROM   [PHOTOS] 
           JOIN [CATEGORIES] 
             ON PHOTOS.CATEGORY = CATEGORIES.ID 
    

    这只返回当前类别或子类别slug,但我也需要父slug才能构建完整的url

    如何在一个选择中从Categories获取所有父节点?

2 个答案:

答案 0 :(得分:2)

您可以使用以下递归查询来构建照片的路径层次结构 它假定slug包含类别的路径,例如category-slug,因此在表达中我与&#39; /&#39;

连接
WITH categoryPath(Id,Slug)
AS
(
    SELECT Id,Slug FROM Categories
    WHERE ParentCategoryId IS NULL
    UNION ALL
    SELECT Categories.Id
          ,CAST(categoryPath.Slug + '/' + categories.Slug AS NVARCHAR(150))  
    FROM Categories
         JOIN categoryPath ON Categories.ParentCategoryId=categoryPath.Id
)
SELECT * FROM Photos 
              JOIN categoryPath ON Photos.CategoryId = categoryPath.Id;

答案 1 :(得分:1)

您需要加入以引入类别表两次。我已经完成了下面的左连接,以防一些照片属于顶级类别。如果没有,你可以删除“左”。

select p.*,c1.*,c2.*
from
    Photos p
    JOIN Categories c1 on
        p.CategoryId = c1.Id
    LEFT JOIN Categories c2 on
        c1.ParentCategoryId = c2.Id

或者如果你可能有任何数量的“世代”父母,你需要做一些递归......我看到有人打败了我!