-2

可能重复:
如何在sql中按每周到最后六个星期日的日期进行分组?

我需要计算周数。它工作正常,但我不知道是 [34]、[35]、[36]、[37]、[38]、[39] 的星期几。weekno 仅在运行时知道。例如,一年中它总共包含 52 周。我在@Bluefeet 的帮助下得到了这个查询,他在同一个stackoverflow 上发布了这个查询。如果我在 between 字段中更改起始日期和截止日期,它将不起作用。因为我在下面的查询中硬编码了 weekno。无论一年中中间字段的日期如何,请给我解决方案。

SET DATEFIRST 1 
SELECT case when InstanceType is not null then InstanceType else 'Sum' End InstanceType ,  
  sum([34]) AS FirstWeek, 
  sum([35]) AS SecondWeek, 
  sum([36]) AS ThirdWeek, 
  sum([37]) AS FourthWeek, 
  sum([38]) AS FifthWeek, 
  sum([39]) AS SixthWeek,  
  max(InstanceDescription) AS InstanceDescription 
FROM 
( 
  SELECT [SPGI01_INSTANCE_TYPE_C] AS InstanceType, 
    [34], [35], [36], [37], [38], [39], InstanceDescription  
  FROM 
  ( 
    SELECT I01.[SPGI01_INSTANCE_TYPE_C], 
      DatePart(wk, I01.[SPGI01_CREATE_S]) WeekNo, 
      DATEADD(DAY, 7 -DATEPART(WEEKDAY,I01.[SPGI01_CREATE_S]),  I01.[SPGI01_CREATE_S]) WeekEnd, 
      J03.SPGJ03_MSG_TRANSLN_X InstanceDescription  
    FROM [SUPER-G].[dbo].[CSPGI01_ASN_ACCURACY] I01  
    INNER JOIN [SUPER-G].[dbo].[CSPGI50_VALID_INSTANCE_TYPE] I50 
      ON I50.[SPGI50_INSTANCE_TYPE_C] = I01.[SPGI01_INSTANCE_TYPE_C]  
    LEFT JOIN CSPGJ02_MSG_OBJ J02 
      ON I50.SPGJ02_MSG_K = J02.SPGJ02_MSG_K  
    LEFT JOIN CSPGJ03_MSG_TRANSLN J03 
      ON J02.SPGJ02_MSG_K = J03.SPGJ02_MSG_K  
    where I50.[SPGA04_RATING_ELEMENT_D] = 1  
      and I01.[SPGI01_EXCEPTIONED_F] = 'N' 
      and I01.[SPGI01_DISPUTED_F] != 'Y'  
      AND J03.[SPGJ03_LOCALE_C] =  'en_US'  
      and I01.[SPGA02_BUSINESS_TYPE_C] = 'PROD'  
      and I01.[SPGA03_REGION_C] = 'EU'  
      and I01.[SPGI01_SUB_BUSINESS_TYPE_C] = 'PRD'  
      and I01.[SPGI01_CREATE_S] between '10-08-2012 00:00:00.000' AND '11-18-2012 23:59:59.000'  
  ) x 
  pivot 
  ( 
    count(WeekEnd) 
    FOR weekno IN ([34], [35], [36], [37], [38], [39])  
  ) p 
) x1 
GROUP BY  InstanceType WITH ROLLUP 
4

1 回答 1

5

如果您希望能够传入任何日期值以获取符合您条件的数据,那么对于这种类型的PIVOT您将需要使用类似于以下的动态 SQL 解决方案:

DECLARE @cols AS NVARCHAR(MAX),
    @colsRollup AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX),
    @StartDate DateTime,
    @EndDate DateTime

Set @StartDate = '10-08-2012 00:00:00.000'
Set @EndDate = '11-18-2012 23:59:59.000'

select @cols = STUFF((SELECT ',' + QUOTENAME(WeekEnd) 
                    from
                    (
                      select DatePart(wk, I01.[SPGI01_CREATE_S]) WeekEnd
                      from [SUPER-G].[dbo].[CSPGI01_ASN_ACCURACY]
                      where I01.[SPGI01_CREATE_S] between @StartDate AND @EndDate
                    ) src
                    group by WeekEnd
                    order by WeekEnd desc
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @colsRollup = STUFF((SELECT ', Sum(' + QUOTENAME(WeekEnd) +') as WeekNo'+Cast(Weekend as varchar(2))
                    from
                    (
                      select DatePart(wk, I01.[SPGI01_CREATE_S]) WeekEnd
                      from [SUPER-G].[dbo].[CSPGI01_ASN_ACCURACY]
                      where I01.[SPGI01_CREATE_S] between @StartDate AND @EndDate
                    ) src
                    group by WeekEnd
                    order by WeekEnd desc
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = '
             SELECT case when InstanceType is not null then InstanceType else ''Sum'' End InstanceType ,  
                '+@colsRollup+',  max(InstanceDescription) AS InstanceDescription
             FROM
             (
               SELECT SPGI01_INSTANCE_TYPE_C as InstanceType,
                    InstanceDescription, ' + @cols + ' 
               from 
               (
                  SELECT I01.[SPGI01_INSTANCE_TYPE_C], 
                    DatePart(wk, I01.[SPGI01_CREATE_S]) WeekNo, 
                    DATEADD(DAY, 7 -DATEPART(WEEKDAY,I01.[SPGI01_CREATE_S]),  I01.[SPGI01_CREATE_S]) WeekEnd, 
                    J03.SPGJ03_MSG_TRANSLN_X InstanceDescription  
                  FROM [SUPER-G].[dbo].[CSPGI01_ASN_ACCURACY] I01  
                  INNER JOIN [SUPER-G].[dbo].[CSPGI50_VALID_INSTANCE_TYPE] I50 
                    ON I50.[SPGI50_INSTANCE_TYPE_C] = I01.[SPGI01_INSTANCE_TYPE_C]  
                  LEFT JOIN CSPGJ02_MSG_OBJ J02 
                    ON I50.SPGJ02_MSG_K = J02.SPGJ02_MSG_K  
                  LEFT JOIN CSPGJ03_MSG_TRANSLN J03 
                    ON J02.SPGJ02_MSG_K = J03.SPGJ02_MSG_K  
                  where I50.[SPGA04_RATING_ELEMENT_D] = 1  
                    and I01.[SPGI01_EXCEPTIONED_F] = ''N'' 
                    and I01.[SPGI01_DISPUTED_F] != ''Y''  
                    AND J03.[SPGJ03_LOCALE_C] =  ''en_US''  
                    and I01.[SPGA02_BUSINESS_TYPE_C] = ''PROD'' 
                    and I01.[SPGA03_REGION_C] = ''EU''  
                    and I01.[SPGI01_SUB_BUSINESS_TYPE_C] = ''PRD''
                    and I01.[SPGI01_CREATE_S] between '+ convert(varchar(10), @StartDate, 120)+' AND '+ convert(varchar(10), @EndDate, 120)+'
              ) x
              pivot 
              (
                  count(WeekEnd)
                  for weekno in (' + @cols + ')
              ) p 
             ) x1
             GROUP BY InstanceType WITH ROLLUP '

execute(@query)

注意:这是未经测试的,因为我没有任何样本数据等。

于 2012-11-29T10:35:53.053 回答