SQL父-子和继承

SQL父-子和继承,sql,sql-server,Sql,Sql Server,我正在使用SQL Server 2016,希望有人能帮我解决这个难题 我有一个表,它保存了相同记录及其属性之间的关系。这是一个示例表 CREATE TABLE [Family] ([Id] Int NOT NULL, [Relation] VARCHAR(12), [Level] TinyInt, [Shoes] VARCHAR(12), [Shirt] VARCHAR(12), [Coat] VARCHAR(12)) INSERT INTO [Family] ([Id], [Relatio

我正在使用SQL Server 2016,希望有人能帮我解决这个难题

我有一个表,它保存了相同记录及其属性之间的关系。这是一个示例表

CREATE TABLE [Family] ([Id] Int NOT NULL, [Relation] VARCHAR(12), [Level] TinyInt,  [Shoes] VARCHAR(12), [Shirt] VARCHAR(12), [Coat] VARCHAR(12))

INSERT INTO [Family] ([Id], [Relation], [Level], [Shoes], [Shirt], [Coat])
   VALUES (1, 'Grandparent', 1, 'Blue', 'Brown', 'Green'),
          (1, 'Parent',2, 'Red', NULL, NULL),
          (1, 'Child', 3, NULL, 'Yellow', NULL),
          (2, 'Grandparent', 1, 'Purple', 'Grey', 'Blue'),
          (2, 'Parent',2, NULL, 'Brown', 'Green')
          (2, 'Child', 3, NULL, NULL, 'Yellow');
关键字段是Id和级别。规则是,我希望能够为每个id选择并返回一行,其中属性返回的是最高级别不为null的行。i、 e如果值为空,则从下一个较低级别继承

我希望我的解释是正确的,因此结果如下:

Id          Shoes  Shirt  Coat
----------- ------ ------ ------
1           Red    Yellow Green
2           Purple Brown  Yellow
我尝试过使用ISNULL和函数的几种方法,但它们最终会变得一团糟,而且速度很慢。当然,我在这里发布的是一个简单的示例,实际表将有8-10个级别和20多个属性列,我需要它在大型数据集上执行


我四处搜寻,没有找到任何真正匹配的,谢谢你。我想到的第一件事是下一个想法:

select f.Id,shoes.Shoes,shirt.Shirt,coat.Coat from [Family] f
left join (select top 1 with ties Id,Shoes from [Family] order by ROW_NUMBER() over (partition by Id order by case when Shoes is not null then [Level] else null end) desc) shoes
    on shoes.Id = f.Id
left join (select top 1 with ties Id,Shirt from [Family] order by ROW_NUMBER() over (partition by Id order by case when Shirt is not null then [Level] else null end) desc) shirt
    on shirt.Id = f.Id
left join (select top 1 with ties Id,Coat from [Family] order by ROW_NUMBER() over (partition by Id order by case when Coat is not null then [Level] else null end) desc) coat
    on coat.Id = f.Id
group by f.Id,shoes.Shoes,shirt.Shirt,coat.Coat
order by f.Id
我只是想试试这个。 显然,一个DISTINCT是在窗口函数之后处理的,如

结果:


rextester上的一个测试

我忘了提到这段代码是使用2008 R2版本编写的:当然,最好使用适用于2012和更高版本的FIRST_VALUE函数。谢谢,我不知道FIRST_VALUE
SELECT DISTINCT Id, 
 FIRST_VALUE(Shoes) OVER (PARTITION BY Id ORDER BY IIF(Shoes is null,0,Level) DESC) AS Shoes,
 FIRST_VALUE(Shirt) OVER (PARTITION BY Id ORDER BY IIF(Shirt is null,0,Level) DESC) AS Shirt,
 FIRST_VALUE(Coat)  OVER (PARTITION BY Id ORDER BY IIF(Coat is null,0,Level) DESC) AS Coat
FROM Family;
Id  Shoes   Shirt   Coat

1   Red     Yellow  Green
2   Purple  Brown   Yellow