3

私は正常に動作している再帰的な CTE を持っていますが、もう 1 つ必要です。各結果に [isLeaf] フラグを追加することです。これにより、レコードにさらに子があるかどうかがわかります (子カウンターを持つ [Leafs] フィールドはさらに良いでしょう)。

以下に貼り付けた作業例。すべてのカテゴリのレベルをカウントし、名前をカテゴリ パスに結合しますが、SQL サーバーでは、LEFT JOIN、TOP、SELECT DISTINCT、集計、およびサブクエリを CTE の再帰部分で使用することは許可されていません。必要。

DROP TABLE cats
GO
create table cats(
    catid int primary key clustered,
    parent int, --parent's catid. 0 for top-level entries
    name    varchar(255)
)
GO

insert into cats (catid, parent, name)
select 1 as catid, 0 as parent, 'computers' as name union all 
    select 2, 1, 'laptops' union all 
        select 4, 2, 'ibm' union all 
        select 5, 2, 'others' union all 
    select 3, 1, 'desktops' union all 
        select 6, 3, 'amd' union all 
        select 7, 3, 'others' union all 
select  8, 0 , 'cars' union all 
    select 9, 8, 'others' union all 
    select 10, 8, 'pickups' union all 
        select 11, 10, 'others' union all 
        select 12, 10, 'ford' union all 
            select 14, 12, 'ranger' union all 
            select 15, 12, 'others'
GO      

;with cteCat as (
    select 
        CatId, Parent,
        [cteLevel]  = 1,
        [ctePath]   = cast(Name as varchar(4000))
        --,[cteIsLeaf]  = 0
    from cats
    where 1=1
        and Parent=0
union all 
    select 
        c.CatId, c.Parent,
        [cteLevel] = cc.cteLevel+1,
        [ctePath] = cast(cc.ctePath + ' | ' + c.Name as varchar(4000))
        --,[cteIsLeaf]  = 0 --???--
    from cats c
    join cteCat cc
        on c.Parent = cc.CatId
    where 1=1
        and c.Parent<>0
)
select 
    * 
from cteCat
order by 
    catid
4

1 に答える 1

3

最も簡単に実装できるのは、IsLeaf. CatID特定の人が誰かの親かどうかを確認する簡単なチェックです。再帰を必要としません。

SELECT
    * ,  CASE WHEN EXISTS (SELECT * FROM cats c2 WHERE c2.parent = c1.CatID) THEN 0 ELSE 1 END AS IsLeaf
FROM cteCat c1
ORDER BY
    catid

編集:差し迫った子供たちの数だけが必要な場合は[Leafs]、それらを取得するのも簡単です:

SELECT
    * 
    , CASE WHEN EXISTS (SELECT * FROM cats c2 WHERE c2.parent = c1.CatID) THEN 0 ELSE 1 END AS IsLeaf
    , (SELECT COUNT(*) FROM cats c2 WHERE c2.parent = c1.CatID) AS Leafs
FROM cteCat c1
ORDER BY 
    c1.catid

SQLFiddle デモ

ただし、[Leafs]子供と子供のすべての子供の合計カウンターが必要な場合は、CTEを書き直す必要があります(上から下ではなく下から上に移動するため)。

于 2013-08-26T08:08:41.190 に答える