从静态行创建父/子关系

时间:2013-10-08 09:29:52

标签: sql sql-server

通过连接到webservice,我收到一个数据列表。列表中的每个记录都包含三个类别字段,我将其保存在具有以下列标记的产品表中:

CategoryName    SubCategoryName    SubSubCategoryName
-----------------------------------------------------
Men             Clothing           Jeans
Women           Jewelry            Bracelets
Women           Clothing           Hoodies
Men             Clothing           Hoodies

ProductTable:CategoryName | SubCategoryName | SubSubCategoryName

我想要做的是从产品表中提取类别并将它们保存到具有父/子关系的表中。

Id     ParentId    CategoryName         
-------------------------------
1      NULL        Men
2      1           Clothing
3      2           Jeans
4      NULL        Women
5      4           Jewelry
6      5           Bracelets
7      4           Clothing
8      7           Hoodies
9      2           Hoodies

我可以使用哪种SQL查询来执行此操作?

1 个答案:

答案 0 :(得分:1)

首先,创建一个新表

create table NewCategories (
  ID int IDENTITY(1,1)  primary key,
  ParentID int null,
  Name nvarchar(max)
)

现在,将所有行插入新表(这将分配ID)

insert into NewCategories (Name) 
select distinct CategoryName
from OldCategories

insert into NewCategories (Name) 
select distinct SubCategoryName 
from OldCategories

insert into NewCategories (Name) 
select distinct SubSubCategoryName
from OldCategories

更新NewCategories表,设置ParentID列,一次用于SubCategoryName,一次用于SubSubCategoryName

update nc2
set ParentID = nc1.ID
from NewCategories nc1
   inner join OldCategories oc on oc.CategoryName = nc1.Name
   inner join NewCategories nc2 on oc.SubCategoryName = nc2.Name

update nc2
set ParentID = nc1.ID
from NewCategories nc1
   inner join OldCategories oc on oc.SubCategoryName = nc1.Name
   inner join NewCategories nc2 on oc.SubSubCategoryName = nc2.Name

这假设原始表中没有*CategoryName个重复项。

SQL Fiddle


对于重复项,您可以(稍微复杂一点)

--insert all categories
insert into NewCategories (Name) 
select distinct CategoryName
from OldCategories


--only categories in the "new" table now
insert into NewCategories (ParentID, Name)
select distinct n.ID, o.SubCategoryName 
from OldCategories o
  inner join NewCategories n on o.CategoryName = n.Name

--now subcategories are items with non-null parents, 
-- so we need a double join
insert into NewCategories (ParentID, Name)
select distinct n1.ID, o.SubSubCategoryName 
from OldCategories o
  inner join NewCategories n1 on o.SubCategoryName = n1.Name
  inner join NewCategories n2 on o.CategoryName = n2.Name and n2.ID=n1.ParentID

这是new fiddle,经过修改后可以处理重复项