如何获取分层sql查询的最深层次
我正在使用SQLServer2008 假设我有一个递归层次结构表SalesRegion、whitsalesregionid和ParentSalesRegionId。我需要的是,给定一个特定的SalesRegion(层次结构中的任何位置),检索底层的所有记录 即: SalesRegion,ParentSalesRegionId 1,空 1-1,1 1-2,1 1-1-1,1-1 1-1-2,1-1 1-2-1,1-2 1-2-2,1-2 1-1-1-1,1-1-1 1-1-1-2,1-1-1 1-1-2-1,1-1-2 1-2-1-1,1-2-1 (在我的表格中,我有顺序编号,这些虚线编号只是为了清楚) 因此,如果用户输入1-1,我需要检索SalesRegion 1-1-1-1或1-1-1-2或1-1-2-1(而不是1-2-2)的所有记录。类似地,如果用户输入1-1-2-1,我只需要检索1-1-2-1 我有一个CTE查询,它检索1-1以下的所有内容,但其中包括我不想要的行:如何获取分层sql查询的最深层次,sql,sql-server,hierarchical-data,Sql,Sql Server,Hierarchical Data,我正在使用SQLServer2008 假设我有一个递归层次结构表SalesRegion、whitsalesregionid和ParentSalesRegionId。我需要的是,给定一个特定的SalesRegion(层次结构中的任何位置),检索底层的所有记录 即: SalesRegion,ParentSalesRegionId 1,空 1-1,1 1-2,1 1-1-1,1-1 1-1-2,1-1 1-2-1,1-2 1-2-2,1-2 1-1-1-1,1-1-1 1-1-1-2,1-1-1 1-
WITH SaleLocale_CTE AS (
SELECT SL.SaleLocaleId, SL.SaleLocaleName, SL.AccountingLocationID, SL.LocaleTypeId, SL.ParentSaleLocaleId, 1 AS Level /*Added as a workaround*/
FROM SaleLocale SL
WHERE SL.Deleted = 0
AND (@SaleLocaleId IS NULL OR SaleLocaleId = @SaleLocaleId)
UNION ALL
SELECT SL.SaleLocaleId, SL.SaleLocaleName, SL.AccountingLocationID, SL.LocaleTypeId, SL.ParentSaleLocaleId, Level + 1 AS Level
FROM SaleLocale SL
INNER JOIN SaleLocale_CTE SLCTE ON SLCTE.SaleLocaleId = SL.ParentSaleLocaleId
WHERE SL.Deleted = 0
)
SELECT *
FROM SaleLocale_CTE
提前谢谢
亚历杭德罗。我找到了一个快速的方法来实现这一点,但我希望答案是在一个单一的查询中。所以如果你能想到一个,请分享!如果我更喜欢它,我会投票支持它作为最好的答案 我在上一个查询中添加了一个“级别”列(我将编辑该问题,使此答案清晰),并使用它获取最后一个级别,然后删除我不需要的级别
INSERT INTO @SaleLocales
SELECT *
FROM SaleLocale_GetChilds(@SaleLocaleId)
SELECT @LowestLevel = MAX(Level)
FROM @SaleLocales
DELETE @SaleLocales
WHERE Level <> @LowestLevel
插入@SaleLocales
挑选*
来自SaleLocale_GetChilds(@SaleLocaleId)
选择@LowestLevel=MAX(标高)
来自@SaleLocales
删除@SaleLocales
何处标高@最低标高
构建您的帖子:
; WITH CTE AS
(
SELECT *
FROM SaleLocale_GetChilds(@SaleLocaleId)
)
SELECT
FROM CTE a
JOIN
(
SELECT MAX(level) AS level
FROM CTE
) b
ON a.level = b.level
里面有一些编辑。不停地点击帖子…你在找这样的东西吗:
declare @SalesRegion as table ( SalesRegion int, ParentSalesRegionId int )
insert into @SalesRegion ( SalesRegion, ParentSalesRegionId ) values
( 1, NULL ), ( 2, 1 ), ( 3, 1 ),
( 4, 3 ), ( 5, 3 ),
( 6, 5 )
; with CTE as (
-- Get the root(s).
select SalesRegion, CAST( SalesRegion as varchar(1024) ) as Path
from @SalesRegion
where ParentSalesRegionId is NULL
union all
-- Add the children one level at a time.
select SR.SalesRegion, CAST( CTE.Path + '-' + cast( SR.SalesRegion as varchar(10) ) as varchar(1024) )
from CTE inner join
@SalesRegion as SR on SR.ParentSalesRegionId = CTE.SalesRegion
)
select *
from CTE
where Path like '1-3%'
我还没有在一个严肃的数据集上尝试过这一点,所以我不确定它将如何执行,但我相信它解决了您的问题:
WITH SaleLocale_CTE AS (
SELECT SL.SaleLocaleId, SL.SaleLocaleName, SL.AccountingLocationID, SL.LocaleTypeId, SL.ParentSaleLocaleId, CASE WHEN EXISTS (SELECT 1 FROM SaleLocal SL2 WHERE SL2.ParentSaleLocaleId = SL.SaleLocaleID) THEN 1 ELSE 0 END as HasChildren
FROM SaleLocale SL
WHERE SL.Deleted = 0
AND (@SaleLocaleId IS NULL OR SaleLocaleId = @SaleLocaleId)
UNION ALL
SELECT SL.SaleLocaleId, SL.SaleLocaleName, SL.AccountingLocationID, SL.LocaleTypeId, SL.ParentSaleLocaleId, CASE WHEN EXISTS (SELECT 1 FROM SaleLocal SL2 WHERE SL2.ParentSaleLocaleId = SL.SaleLocaleID) THEN 1 ELSE 0 END as HasChildren
FROM SaleLocale SL
INNER JOIN SaleLocale_CTE SLCTE ON SLCTE.SaleLocaleId = SL.ParentSaleLocaleId
WHERE SL.Deleted = 0
)
SELECT *
FROM SaleLocale_CTE
WHERE HasChildren = 0
最大深度是否为4?如果是这样,这也是任何分支的最小最终深度吗?@Norla Nope,最大层数未知。。。但我确实需要最后一级中的任何内容,我将编辑问题以明确这一点。谢谢如果您有调整结构的优势,您可能需要考虑SythyYID数据类型。它使这样的查询变得容易(而且通常要快得多)。类似于<代码>选择。。。从SL中,myHierarchy.isDecendaTof(@value)或myHerarchyID.GetGenerant(@child1,@child2)。这比我的解决方法要好,但我会等待其他人是否给我一个不需要使用该函数的答案。谢谢