2012-11-19 141 views
0

我有一個表:聚合列進年度/每月/每週

Table A 
------- 
SubscriberId int 
ContentId int 
SendDate DateTime 

Sample Data 
------------ 
1   190159  2012-11-07 00:00:00.000 
1   190160  2012-11-07 00:00:00.000 
1   190160  2012-11-07 00:00:00.000 
1   190160  2012-11-07 00:00:00.000 
1   190160  2012-11-07 00:00:00.000 
1   190160  2012-11-07 00:00:00.000 
1   190160  2012-11-07 00:00:00.000 
1   190160  2012-11-19 00:00:00.000 
2   190160  2012-11-19 00:00:00.000 
2   190160  2012-10-19 00:00:00.000 
2   190160  2012-10-01 00:00:00.000 
2   190160  2011-10-01 00:00:00.000 
2   190160  2011-10-01 00:00:00.000 
2   190160  2011-10-01 00:00:00.000 
2   190160  2011-10-19 00:00:00.000 
2   190160  2011-10-18 00:00:00.000 
2   190160  2011-10-17 00:00:00.000 
2   190161  2011-10-20 00:00:00.000 
2   190161  2011-10-01 01:01:01.000 

上表是一個平坦的桌面,而不是標準化的(我打算繼續保持這種方式)

輸出我需要的是,每個SubscriberId我需要統計CONTENTIDS爲Senddate每年,每月和每週的數量和以特定方式格式化:

Subscriber ID YEARLYValidData 
1    190159,1|190160,7 
2    190160,9|190161,2 

上述結果是部分結果即。我得到的結果是爲YEARLY數據工作,但是在第二列中,我需要MONTHLYValiddata(即這30天瀑布從GETDATE()),我的內容還需要WEEKLYValidData(即7天瀑布從GETDATE即內容())

下面的查詢給了我想要的結果,但分開它們:

DECLARE NumberOfDays int = 365 
SELECT MAIN.SubscriberId, 
      STUFF((
       SELECT '|' + 
       (CAST(SUB.ContentId AS nvarchar(10)) + ',' + 
       CAST(Count(ContentId) as nvarchar(100))) 
       FROM TABLEA SUB 
       Where 
       SUB.SubscriberId = MAIN.SubscriberId 
       GROUP BY ContentId 
       FOR XML PATH('') 
       ), 1, 1, '') 
      AS [Result] 
      FROM TABLEA MAIN 
      WHERE 
      DATEADD(DAY, DATEDIFF(DAY, 0, SendDate), 0) >= 
      DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0) - @NumberOfDays 

如何獲得如下的結果在一個單一的SELECT語句:

Subscriber ID YEARLYValidData  MONTHLYValidData   WEEKLYValidData 
1    190159,1|190160,7  190159,1|190160,7  190159,1|190160,7  
2    190160,9|190161,2  190160,9|190161,2  190160,1 

我知道我可以使用臨時表(或表變量),並繼續輸入年/每月/每週的數據,但我想用如果可能,更高效的東西?

回答

1

我不太瞭解,但是這可能會進一步給你一點點沿着路徑,即使它不是最終的答案:

SELECT C.Interval, 
     MAIN.SubscriberId, 
     STUFF((
      SELECT '|' + 
      (CAST(SUB.ContentId AS nvarchar(10)) + ',' + 
      CAST(Count(ContentId) as nvarchar(100))) 
      FROM TABLEA SUB 
      Where 
      SUB.SubscriberId = MAIN.SubscriberId 
      GROUP BY ContentId 
      FOR XML PATH('') 
      ), 1, 1, '') 
     AS [Result] 
     FROM TABLEA MAIN 
     CROSS JOIN 
     ( SELECT 356 As Days, 'Year' As Interval 
      UNION ALL 
      SELECT 30 Days, 'Month' As Interval 
      UNION ALL 
      SELECT 7 Days, 'Week' As Interval 
     ) C 
     WHERE 
     DATEADD(DAY, DATEDIFF(DAY, 0, SendDate), 0) >= 
     DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0) - C.Days