获取使用 hierarchyId 创建的符合某些条件的树中的最低级别
Get Lowest level in tree created with hierarchyId that respect some conditions
我在 SQL 服务器中创建了层次结构 table。我有一列 hierarchyId。每个级别代表一个国家的 geographical/political 级别:
- 国家
- 地区
- 省份
对于每一行,我都可以填充或不填充一些边界。为了简化,我在示例中将 geometry
列替换为 bit
列。
我需要获得已填充边界的最低级别。如果至少有一个 child 有边界,那么 parent 肯定也有边界。
我举个例子:
例如,我有那棵树。在我的查询中,我应该得到绿色和红色区域。在这一刻我只得到绿色区域..所以,我应该得到:
- Valle d'aosta 因为是最低层而且有边界(没关系);
- Milano和Brescia因为他们是最低层,有边界。我不应该得到 Bergamo 因为它没有边界,但我应该得到 Lombardia 而不是 Bergamo;
- 意大利因为皮埃蒙特和都灵都没有边界;
- 拉齐奥因为罗马没有边界。
我的查询部分正确。我得到了所有最低级别。但是我没有得到符合我条件的最低高水平..
我分享一个link的例子:http://sqlfiddle.com/#!18/878577/1
这里还有您可以在 sql fiddler 中看到的查询:
select * from country_subdivisions cs
where IsoCode IN(
select cs.IsoCode
from parent p
where cs.Level.IsDescendantOf(p.Level) = 1
and p.CountryISOAlpha2Code = cs.CountryISOAlpha2Code
-- and (cs.Level.GetLevel() = p.Level.GetLevel() + 1 or cs.Level.GetLevel() = p.Level.GetLevel())
and cs.Level.GetLevel() = (SELECT MAX(leaf.Level.GetLevel()) FROM country_subdivisions leaf WHERE leaf.Level.IsDescendantOf(cs.Level) = 1 and leaf.HasBoundaries = 1)
)
如您所见,我正确地得到了绿色区域,但没有得到红色区域。
有什么想法吗?我说清楚了吗?
谢谢
我觉得逻辑总结如下:
Return一个parent当:
- 那parent有边界,
- 或者:
- 没有children,或者
- 它至少有一个 child 没有边界。
这可以表述如下:
select parent.*
from country_subdivisions parent
where parent.HasBoundaries = 1
and 0 < (select case
when count(*) = 0 then 1
else count(case when child.HasBoundaries = 0 then 1 end)
end
from country_subdivisions child
where child.Level.GetAncestor(1) = parent.Level
);
我在 SQL 服务器中创建了层次结构 table。我有一列 hierarchyId。每个级别代表一个国家的 geographical/political 级别:
- 国家
- 地区
- 省份
对于每一行,我都可以填充或不填充一些边界。为了简化,我在示例中将 geometry
列替换为 bit
列。
我需要获得已填充边界的最低级别。如果至少有一个 child 有边界,那么 parent 肯定也有边界。
我举个例子:
例如,我有那棵树。在我的查询中,我应该得到绿色和红色区域。在这一刻我只得到绿色区域..所以,我应该得到:
- Valle d'aosta 因为是最低层而且有边界(没关系);
- Milano和Brescia因为他们是最低层,有边界。我不应该得到 Bergamo 因为它没有边界,但我应该得到 Lombardia 而不是 Bergamo;
- 意大利因为皮埃蒙特和都灵都没有边界;
- 拉齐奥因为罗马没有边界。
我的查询部分正确。我得到了所有最低级别。但是我没有得到符合我条件的最低高水平..
我分享一个link的例子:http://sqlfiddle.com/#!18/878577/1
这里还有您可以在 sql fiddler 中看到的查询:
select * from country_subdivisions cs
where IsoCode IN(
select cs.IsoCode
from parent p
where cs.Level.IsDescendantOf(p.Level) = 1
and p.CountryISOAlpha2Code = cs.CountryISOAlpha2Code
-- and (cs.Level.GetLevel() = p.Level.GetLevel() + 1 or cs.Level.GetLevel() = p.Level.GetLevel())
and cs.Level.GetLevel() = (SELECT MAX(leaf.Level.GetLevel()) FROM country_subdivisions leaf WHERE leaf.Level.IsDescendantOf(cs.Level) = 1 and leaf.HasBoundaries = 1)
)
如您所见,我正确地得到了绿色区域,但没有得到红色区域。
有什么想法吗?我说清楚了吗?
谢谢
我觉得逻辑总结如下:
Return一个parent当:
- 那parent有边界,
- 或者:
- 没有children,或者
- 它至少有一个 child 没有边界。
这可以表述如下:
select parent.*
from country_subdivisions parent
where parent.HasBoundaries = 1
and 0 < (select case
when count(*) = 0 then 1
else count(case when child.HasBoundaries = 0 then 1 end)
end
from country_subdivisions child
where child.Level.GetAncestor(1) = parent.Level
);