简体   繁体   English

SQL在列中查找每种“动态”类型的总数

[英]SQL find total count of each `dynamic` type in a column

I have stored my record data on SQL server and I want to get what should be a simple query to get the total count of each type of my record. 我已将记录数据存储在SQL Server上,我想获得一个简单的查询来获取每种记录类型的总数。 I have a table with the following pattern: 我有一个具有以下模式的表:

Id |  Type  | ID_Type |
-----------------------
1  |  Bags  |   B1    |
2  |  Shoes |   S1    |
3  |  Shoes |   S1    | 
4  |  Bags  |   B1    |  
..

The Type of my record is dynamic it's working like a category if the user added new Type like Shirts and created new record my query should also get the total of Shirts . 我的记录的Type是动态的,如果用户添加了新的类型(例如Shirts并创建了新记录,则我的记录的工作方式就像一个类别,我的查询也应该获得Shirts的总数。 Here's my sample data: 这是我的示例数据:

Id |   Type   | ID_Type |
------------------------
1  |   Bags   |   B1    |
2  |   Shoes  |   S1    |
3  |   Shoes  |   S1    | 
4  |   Bags   |   B1    |  
5  |  Shirts  |   S2    |
6  |  Shirts  |   S2    |
7  |  Shirts  |   S2    |
..

Below is the result I would like to get with total of records: 以下是我希望获得的记录总数的结果:

 Bags | Shoes | Shirts | Total |
-------------------------------
   2  |   2   |   3    |   7

You can do with case statement in this way. 您可以通过这种方式处理case语句。

with cte as (

Select 1 as ID, 'Bags'   as [Type] union all  
Select 2 as ID, 'Shoes'  as [Type] union all  
Select 3 as ID, 'Shoes'  as [Type] union all  
Select 4 as ID, 'Bags'   as [Type] union all 
Select 5 as ID, 'Shirts' as [Type] union all 
Select 6 as ID, 'Shirts' as [Type] union all 
Select 7 as ID, 'Shirts' as [Type]  ) 

select count(case when [type] ='Bags' then ID end) Bags, count(case when [type] 
='Shoes' then ID end) Shoes , 
count(case when [type] ='Shirts' then ID end) Shirts, count(1) total  from cte;

Output: 输出:

 Bags   Shoes Shirts  total
  2      2     3       7

Using Dynamic SQL approach: 使用动态SQL方法:

IF the columns are dynamic then you can achieve your results in this way. 如果列是动态的,则可以通过这种方式获得结果。

Test Data: 测试数据:

 -- drop table #temp
Select 1 as ID, 'Bags'   as [Type] into #temp  union all  
Select 2 as ID, 'Shoes'  as [Type] union all  
Select 3 as ID, 'Shoes'  as [Type] union all  
Select 4 as ID, 'Bags'   as [Type] union all 
Select 5 as ID, 'Shirts' as [Type] union all 
Select 6 as ID, 'Shirts' as [Type] union all 
Select 7 as ID, 'Shirts' as [Type] 

--drop table #temp1
select *, ROW_NUMBER() over (partition by [Type] order by ID) Rownum  
into #temp1 from #temp 



DECLARE @cols AS NVARCHAR(MAX),
@query  AS NVARCHAR(MAX);

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.Type) 
    FROM #temp c
    FOR XML PATH(''))  
,1,1,'')

 set @query = 'SELECT   '+@cols+' ,total  from 
    (
        select Type, ID, total 

            from #temp1  t  
            join (select count(1) total from #temp1) t1 on 1= 1 
   ) x
    pivot 
    (
         count(ID) 
        for Type in (' + @cols + ')
    ) p '

 Exec sp_executesql  @query

Output: 

Bags     Shirts Shoes total 
2         3      2     7

You can create dynamic PIVOT like following. 您可以创建动态PIVOT ,如下所示。 To generate the Total column you can simply use WITH ROLLUP in GROUP BY 要生成“ Total列,您只需在GROUP BY使用WITH ROLLUP

DECLARE @cols AS NVARCHAR(max) = Stuff((SELECT DISTINCT ', ' + Quotename([Type]) 
             FROM   [YourTableName]
             FOR xml path(''), type).value('.', 'NVARCHAR(MAX)'), 1, 1, '') + ',[Total]'; 

EXECUTE('SELECT * FROM (select ISNULL(type, ''total'') as Type,Count(*) n 
                   from  [YourTableName] GROUP BY [Type] WITH ROLLUP) s
                    PIVOT (max(n) FOR [Type] IN ('+@cols+') ) pvt')

Online Demo 在线演示

Output 产量

+------+--------+-------+-------+
| Bags | Shirts | Shoes | Total |
+------+--------+-------+-------+
| 2    | 3      | 2     | 7     |
+------+--------+-------+-------+

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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