简体   繁体   English

sql server动态透视

[英]sql server dynamic pivoting

I need suggestion on summary report. 我需要关于总结报告的建议。 I have a table like below(few sample records). 我有一个像下面的表(一些示例记录)。 I have devices installed in stores(many to many relationship between device and store). 我在商店中安装了设备(设备与商店之间有很多关系)。 calculate count in a list of devices(Assume 300 to 320) over a period of time(assume one year). 计算一段时间(假设一年)内设备列表(假设300到320)中的计数。 If deviceid exist in list then count will be added to appropriate month. 如果列表中存在deviceid,则将计数添加到适当的月份。 If deviceid is present in time period but not in the list then others count will increase. 如果设备ID在该时间段中存在但不在列表中,则其他计数将增加。

I prepared an dynamic pivot query to get counts for one year data. 我准备了一个动态数据透视查询,以获取一年数据的计数。 Query is working for a list of devices. 查询正在为设备列表工作。 But i am confused to get the other device count. 但是我很困惑要获取其他设备的数量。 Please suggest or give some inputs or dynamic query. 请提出建议或提供一些意见或动态查询。 Thanks in advance. 提前致谢。 Sorry for my poor english. 对不起,我英语不好。

Input Table: 输入表:
deviceid,storeid,saledate deviceid,storeid,saledate
306,44070,2006-02-02 21:58:29.790 306,44070,2006-02-02 21:58:29.790
307,44071,2006-03-02 22:00:08.853 307,44071,2006-03-02 22:00:08.853
306,44070,2006-04-02 22:14:36.773 306,44070,2006-04-02 22:14:36.773
308,44071,2006-04-02 22:15:31.320 308,44071,2006-04-02 22:15:31.320
306,44072,2006-02-18 13:39:18.380 306,44072,2006-02-18 13:39:18.380
307,44073,2006-03-18 13:46:55.397 307,44073,2006-03-18 13:46:55.397
392,44070,2006-02-18 13:53:47.647 392,44070,2006-02-18 13:53:47.647
307,44070,2006-04-18 14:03:23.930 307,44070,2006-04-18 14:03:23.930
308,44071,2006-02-19 14:54:06.930 308,44071,2006-02-19 14:54:06.930
390,44070,2006-04-12 15:16:51.537 390,44070,2006-04-12 15:16:51.537

Output1:(count per month per device) 输出1 :(每台设备每月的计数)
deviceid,[Feb-06],[Mar-06],[Apr-06] deviceid,[Feb-06],[Mar-06],[Apr-06]
306,2,0,1 306,2,0,1
307,0,2,1 307,0,2,1
308,2,0,0 308,2,0,0
Others,1,0 , 1 其他1,1,0

Output2:(distinct store count per device per month) 输出2 :(每个设备每月的不同商店数)
deviceid,storeid,[Feb-06],[Mar-06],[Apr-06] deviceid,storeid,[Feb-06],[Mar-06],[Apr-06]
306,2,2,0, 1 306,2,2,0,1
307,3,0,2 , 1 307,3,0,2,1
308,1,2,0,0 308,1,2,0,0
Others,1,1 ,0 , 1 其他,1,1,0,1

Try this and change accordingly 试试这个,并进行相应的更改

DECLARE @COLS VARCHAR(MAX);
DECLARE @COLS_ALIAS VARCHAR(MAX);
DECLARE @SQL NVARCHAR(MAX);

select @cols = STUFF((SELECT  DISTINCT ',' + QUOTENAME(Datename(MONTH, Sale_Date))
                from #Your_table
        FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'');
select @COLS_ALIAS = STUFF((SELECT  DISTINCT ',ISNULL(Max(' + QUOTENAME(Datename(MONTH, Sale_Date))+ '),0) AS '+ QUOTENAME(Datename(MONTH, Sale_Date))
            from #Your_table
    FOR XML PATH(''), TYPE
    ).value('.', 'NVARCHAR(MAX)') 
,1,1,'');


SET @SQL='SELECT A.DEVICE_ID,
       YEAR,
       RN AS COUNT_DISTINCT,'+@cols+'
FROM   (SELECT TEMP                        AS DEVICE_ID,
               Max(YEAR)                   YEAR,
               Max(COUNT1)                 AS COUNT,'+@COLS_ALIAS+'
        FROM   (SELECT A.Device_id,
                       Count(A.Device_id)         AS COUNT,
                       Count(A.Device_id)         AS COUNT1,
                       Datename(MONTH, Sale_Date) AS MONTH,
                       Year(Sale_Date)            AS YEAR,
                       ( CASE
                           WHEN A.Device_id = 306 THEN ''306''
                           WHEN A.Device_id = 307 THEN ''307''
                           WHEN A.Device_id = 308 THEN ''308''
                           ELSE ''Others''
                         END )                    AS TEMP
                FROM   #Your_table A
                GROUP  BY A.Device_id,
                          Datename(MONTH, Sale_Date),
                          Year(Sale_Date)) A
               PIVOT (Max(COUNT)
                     FOR MONTH IN ('+@COLS+'))PV
        GROUP  BY TEMP)A
       JOIN (SELECT TEMP    AS Device_id,
                    Sum(RN) AS RN
             FROM   (SELECT Device_id,
                            Row_number()
                              OVER(
                                PARtition BY DEvice_id, Store_id
                                ORDER BY device_id) AS RN,
                            ( CASE
                           WHEN Device_id = 306 THEN ''306''
                           WHEN Device_id = 307 THEN ''307''
                           WHEN Device_id = 308 THEN ''308''
                           ELSE ''Others''
                         END )                    AS TEMP
                     FROM   #Your_table)A
             WHERE  RN = 1
             GROUP  BY TEMP)B
         ON A.Device_id = B.Device_id'

EXECUTE sp_executesql @SQL

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

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