可能重复:
How to group by the each week upto last six week sundays dates in sql?
我需要计算一周的数量。它工作正常,但我不知道[34],[35],[36],[37],[38],[39]的周。 weekno只知道运行时。例如,在一年中它总共包含52周。我在@Bluefeet的帮助下得到了这个查询,他在同一个stackoverflow上发布了查询。如果我更改日期和日期之间的字段,它不起作用。因为我在下面的查询中硬编码了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
答案 0 :(得分: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)
注意:这是未经测试的,因为我没有任何样本数据等。