我有3张桌子:
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
)
Region表是递归的,因为区域可以有父区域,如果父id是null,那么它是顶级区域。区域可能达到4个级别。
我需要为每个级别的每个区域获取一个项目计数。如果一个地区是父母 - 我需要将所有孩子的数量减少到尽可能多的水平和分支。换句话说,如果区域255具有父级130并且130具有父级67并且67具有父级2,则我需要2的计数(包括所有子级和分支)以及67的计数,包括其所有子级和分支等等。我需要在一次通话中为所有地区获取此信息。这是否可以使用递归查询?
答案 0 :(得分:3)
试试这个:
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
答案 1 :(得分:1)
这样做的一种方法是在递归查询的初始部分中包含额外的列。这允许您“传递”递归开始的位置。在下面的示例中,额外的列记住Root_id和Root_name。这应该列出所有地区及其总项目数:
; 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