Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2005 这种讨厌的递归在T-SQL中可能吗?_Sql Server 2005_Tsql_Recursion - Fatal编程技术网

Sql server 2005 这种讨厌的递归在T-SQL中可能吗?

Sql server 2005 这种讨厌的递归在T-SQL中可能吗?,sql-server-2005,tsql,recursion,Sql Server 2005,Tsql,Recursion,我有三张桌子: Region ( Region_id int, Parent_id int, Region_name varchar(50) ) RegionStore ( Region_id int, Store_id int ) StoreItems ( Store_id int, Item_id int ) 区域表是递归的,因为区域可以有父区域,如果父id为null,则为顶级区域。区域可能达到4个级别 我需要得到每一个级别的每个

我有三张桌子:

Region
(
    Region_id int,
    Parent_id int,
    Region_name varchar(50)
)

RegionStore
(
    Region_id int,
    Store_id int
)

StoreItems
(
    Store_id int,
    Item_id int
)
区域表是递归的,因为区域可以有父区域,如果父id为null,则为顶级区域。区域可能达到4个级别


我需要得到每一个级别的每个区域的物品数量。如果一个区域是一个父区域,我需要它的所有子区域的计数,以及它的级别和分支。换句话说,如果区域255有父级130,130有父级67,67有父级2,我需要一个计数2(包括所有子级和分支)和一个计数67(包括其所有子级和分支),以此类推。我需要在一次通话中获得所有地区的信息。使用递归查询可以做到这一点吗?

一种方法是在递归查询的初始部分包含额外的列。这允许您“向下传递”递归开始的位置。在下面的示例中,额外的列会记住Root_id和Root_名称。应列出所有区域及其项目总数:

; with  Regions as 
        (
        select  Region_id as Root_id
        ,       Region_name as Root_name
        ,       *
        from    @Region
        union all
        select  p.Root_id
        ,       p.Root_name
        ,       c.*
        from    Regions p
        join    @Region c
        on      p.Region_id = c.Parent_id
        )
select  r.Root_name
,       count(distinct si.Item_id) as ItemCount
from    Regions r
left join 
        @RegionStore rs 
on      rs.Region_id = r.Region_id
left join 
        @StoreItems si 
on      si.Store_id = rs.Store_id
group by
        r.Root_name

一种方法是在递归查询的初始部分包含额外的列。这允许您“向下传递”递归开始的位置。在下面的示例中,额外的列会记住Root_id和Root_名称。应列出所有区域及其项目总数:

; with  Regions as 
        (
        select  Region_id as Root_id
        ,       Region_name as Root_name
        ,       *
        from    @Region
        union all
        select  p.Root_id
        ,       p.Root_name
        ,       c.*
        from    Regions p
        join    @Region c
        on      p.Region_id = c.Parent_id
        )
select  r.Root_name
,       count(distinct si.Item_id) as ItemCount
from    Regions r
left join 
        @RegionStore rs 
on      rs.Region_id = r.Region_id
left join 
        @StoreItems si 
on      si.Store_id = rs.Store_id
group by
        r.Root_name
试试这个:

DECLARE @Region TABLE 
( 
    Region_id int, 
    Parent_id int, 
    Region_name varchar(50) 
) 

DECLARE @RegionStore  TABLE
( 
    Region_id int, 
    Store_id int 
) 

DECLARE @StoreItems TABLE
( 
    Store_id int, 
    Item_id int 
) 

INSERT @Region
SELECT 2, NULL, '2' UNION ALL
SELECT 67, 2, '67' UNION ALL
SELECT 130, 67, '130' UNION ALL
SELECT 255, 130, '255' UNION ALL
SELECT 1, NULL, '1' UNION ALL
SELECT 68, 2, '68' 

-- add more test data here

;WITH CTE AS (
    SELECT  
        Region_id,
        Parent_id,
        Region_name,
        Region_id AS Region_id_calc
    FROM @Region

    UNION ALL   

    SELECT  
        r.Region_id,
        r.Parent_id,
        r.Region_name,
        CTE.Region_id_calc AS Region_id_calc
    FROM CTE
    INNER JOIN @Region AS r
        ON r.Region_id = CTE.Parent_id
)
SELECT  
    CTE.Region_id,
    Region_name,
    COUNT(DISTINCT Item_Id)
FROM CTE
INNER JOIN @RegionStore AS s
    ON CTE.Region_id_calc = s.Region_id
INNER JOIN @StoreItems AS i
    ON s.Store_id = i.Store_id
GROUP BY
    CTE.Region_id,
    Region_name
ORDER BY 
    CTE.Region_id
试试这个:

DECLARE @Region TABLE 
( 
    Region_id int, 
    Parent_id int, 
    Region_name varchar(50) 
) 

DECLARE @RegionStore  TABLE
( 
    Region_id int, 
    Store_id int 
) 

DECLARE @StoreItems TABLE
( 
    Store_id int, 
    Item_id int 
) 

INSERT @Region
SELECT 2, NULL, '2' UNION ALL
SELECT 67, 2, '67' UNION ALL
SELECT 130, 67, '130' UNION ALL
SELECT 255, 130, '255' UNION ALL
SELECT 1, NULL, '1' UNION ALL
SELECT 68, 2, '68' 

-- add more test data here

;WITH CTE AS (
    SELECT  
        Region_id,
        Parent_id,
        Region_name,
        Region_id AS Region_id_calc
    FROM @Region

    UNION ALL   

    SELECT  
        r.Region_id,
        r.Parent_id,
        r.Region_name,
        CTE.Region_id_calc AS Region_id_calc
    FROM CTE
    INNER JOIN @Region AS r
        ON r.Region_id = CTE.Parent_id
)
SELECT  
    CTE.Region_id,
    Region_name,
    COUNT(DISTINCT Item_Id)
FROM CTE
INNER JOIN @RegionStore AS s
    ON CTE.Region_id_calc = s.Region_id
INNER JOIN @StoreItems AS i
    ON s.Store_id = i.Store_id
GROUP BY
    CTE.Region_id,
    Region_name
ORDER BY 
    CTE.Region_id

是-@恶心-是的,我可以让父子关系显示得很好(我实际上使用了一个表变量来代替CTE),但它得到的是我一直坚持的项目计数。我可以在最底层得到它们,但这是我所能得到的。是的-@恶心-是的,我可以让父子关系显示得很好(我实际使用了一个表变量来代替CTE),但它得到的是我一直坚持的项目计数。我可以在最底层得到它们,但这是我所能得到的。看起来你需要将总和转换为COUNT@AndreyGurinov:谢谢,这无可争议是正确的,编辑:)这也行,但网站只允许我将一个标记为答案-uv-谢谢,就像你需要将总和更改为COUNT@AndreyGurinov:谢谢,毫无疑问,这是正确的,编辑:)这也有效,但该网站只允许我将其中一个标记为答案-uv-感谢+80正确使用CTE的无限递归荣耀。我认为如果我改变一件事,并删除与item_id计数不同的内容,这可能会起作用,因为我希望a计数所有项目,而不仅仅是所有类型的项目。我会让你知道的,谢谢。谢谢,祝你好运+我想,如果我改变一件事,去掉与物品id计数不同的东西,这可能会起作用,因为我希望a计数所有物品,而不仅仅是所有类型的物品。我会让你知道的,谢谢。谢谢,祝你好运!