[英]Sql getting count of each category
Consider the following 2 tables 考虑以下2个表
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 如果更高的HigerCatId为0,则意味着我们到达了最高父母,我们应该停止
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?
我能够用c#中的递归来做到这一点,我不知道它是否可以直接来自sql,我的问题是子类别可以有产品,即使它们有更深的子类别,这个结果是以完全动态的方式生成的sql server无论级别的深度如何,或者我应该坚持从外部sql做到这一点?
if its possible can you please give me some ideas? 如果有可能,请你给我一些想法?
200 bounty will be rewarded when i get to start one. 当我开始获得200赏金时,我将获得奖励。
You need a CTE 你需要一个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. 查看SQL Fiddle ,您可以在其中查看结果和一些中间输出。
CTE can create the hierarchy. CTE可以创建层次结构。
XML path can concatinate the columns. XML路径可以连接列。
Count(p.CatId) in combination with GROUP BY will get the exact number of matches(ProductCount) 计数(p.CatId)与GROUP BY组合将获得确切的匹配数(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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.