简体   繁体   English

Sql获取每个类别的计数

[英]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

FIDDLE 小提琴

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM