Consider the following 2 tables
Categories
CatId CatName HigerCatId
1 Clothing 0
2 Jackets 1
3 T-Shirts 1
4 BlueT-Shirts 3
5 White-Jackates 2
if higher HigerCatId is 0 it means we reached the the top parent and we should stop
Products
ProductId CatId
0 3
1 1
2 1
3 2
4 2
5 3
6 4
7 3
8 4
the expected result is
CatName ChildCats ProductsCount ProductIds(Not needed just to give an idea)
Clothing 2,3,4,5 9 0,1,2,3,4,5,6,7,8
Jackets 5 2 3,4
T-Shirts 4 5 0,5,6,7,8
BlueT-Shirts none 2 6,8
White-Jackates none 0 none
all i need is to get the total count of products that fall under a category, the total for the parent should contain the total of all categories under it. i was able to do it with recursion in c# and i have no idea if its even possible directly from sql, my problem is that sub categories can have products even if they have deeper sub categories, is that result producible in a totally dynamic way from sql server no matter how the depth of the levels is or should i stick to do it from outside sql?
if its possible can you please give me some ideas?
200 bounty will be rewarded when i get to start one.
You need a CTE
WITH cte
AS
(
SELECT CatId AS ParentCatId,
CatName,
CatName AS ParentName,
HigherCatId,
CatId,
CAST(CatName AS VARCHAR(255)) AS PATH
FROM Categories
UNION ALL
SELECT c.CatId AS ParentCatId,
cte.CatName,
c.CatName AS ParentName,
c.HigherCatId,
cte.CatId,
CAST(cte.path + ', ' + c.CatName AS VARCHAR(255)) AS PATH
FROM cte
INNER JOIN Categories c
ON c.CatId = cte.HigherCatId
)
SELECT c.parentName,
COUNT(p.ProductId) AS ProductsCount
FROM cte c
LEFT OUTER JOIN products p
ON c.CatId = p.CatId
GROUP BY
c.ParentCatId,
c.ParentName
ORDER BY
c.ParentCatId
There are some extra columns for debugging purposes, you can remove them in your final code.
Check out the SQL Fiddle where you can see the result and some intermediate outputs.
CTE can create the hierarchy.
XML path can concatinate the columns.
Count(p.CatId) in combination with GROUP BY will get the exact number of matches(ProductCount)
;WITH cte AS
(
SELECT
CatId parent,
CatId
FROM Categories
UNION ALL
SELECT
cte.parent,
c.CatId
FROM cte
JOIN
Categories c
ON cte.CatId = c.HigherCatId
)
SELECT c.CatName,
Coalesce(STUFF((
SELECT
',' + cast(t1.CatId as varchar(10))
FROM
cte t1
WHERE
t1.parent = c.CatId and
t1.CatId <> c.CatId
ORDER BY
t1.CatId
for xml path(''), type
).value('.', 'varchar(max)'), 1, 1, ''), 'none') ChildCats,
COUNT(p.CatId) ProductCount,
COALESCE(STUFF((
SELECT ',' + cast(p.ProductId as varchar(10))
FROM cte t1
LEFT JOIN
Products p
ON
t1.CatId = p.CatId
WHERE
t1.parent = c.CatId
ORDER BY
p.ProductId
for xml path(''), type
).value('.', 'varchar(max)'), 1, 1, ''), 'none') ProductIds
FROM
Categories c
JOIN
cte
ON
c.CatId = cte.parent
LEFT JOIN
Products p
ON
cte.CatId = p.CatId
GROUP BY
c.CatId,
c.CatName
ORDER BY
c.CatId
Result:
CatName ChildCat ProductCount ProductIds
Clothing 2,3,4,5 9 0,1,2,3,4,5,6,7,8
Jackets 5 2 3,4
T-Shirts 4 5 0,5,6,7,8
BlueT-Shirts none 2 6,8
White-Jackates none 0 none
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.