每周生成报告

时间:2013-07-05 19:03:37

标签: sql sql-server-2008

我正在尝试每周收到报告,以了解实际使用该产品的数量。

这是我当前的查询

select 
COUNT(*) as 'TotalPurchased',
SUM(case when date<= DATEADD(day, -7, GETDATE())THEN 1 ELSE 0 END) as 'week1' 
from #myreport

我希望输出为

Totalpurchased   week1  week2 week3 ..........so on
  82              80     14    16

它应该到年底。

我从上面的查询中只获得了一周的输出。我正在使用sql 2008 r2环境从临时表中获取数据。

4 个答案:

答案 0 :(得分:7)

如果您想要返回列,可以使用动态sql和PIVOT来执行此操作:

DECLARE @cols AS VARCHAR(8000),
    @query  AS VARCHAR(8000)

SELECT @cols = STUFF((SELECT ',' +   QUOTENAME(YrWeek) 
                    FROM (SELECT DISTINCT CAST(YEAR(rpt_dt)AS VARCHAR(4)) + '-' + CAST(DATEPART(week,rpt_dt)AS VARCHAR(2))'YrWeek'
                          FROM #myreport
                          WHERE rpt_dt > DATEADD(YEAR,-1,GETDATE()))sub
                    ORDER BY LEFT(YrWeek,4) DESC,RIGHT(YrWeek,2)DESC
                   FOR XML PATH(''), TYPE
            ).value('.', 'VARCHAR(MAX)') 
        ,1,1,'')

SET @query = 'SELECT * FROM
                (
                SELECT CAST(YEAR(rpt_dt)AS VARCHAR(4)) + ''-'' + CAST(DATEPART(week,rpt_dt)AS VARCHAR(2)) YrWeek, COUNT(*)CT
                FROM #myreport   
                GROUP BY CAST(YEAR(rpt_dt)AS VARCHAR(4)) + ''-'' + CAST(DATEPART(week,rpt_dt)AS VARCHAR(2))
                ) AS T1
                PIVOT (SUM(CT) FOR YrWeek IN ('+@cols+')) AS T2

'
EXEC(@query)

在这个例子中,从去年开始,它在去年每周都在拉动。

这是一个演示,仅使用日期列表并按日期计算记录,我认为这与您最终要做的事情相同。

SQL Fiddle

答案 1 :(得分:2)

尝试这样的事情(您可能需要根据需要调整日期范围):

SELECT
    COUNT(*) AS 'count',
    CONVERT(nchar(4), DATEPART(year, [date]))
     + '-' + 
    CONVERT(nchar(2), DATEPART(wk, [date])) AS 'week'
FROM #myreport
WHERE
    [date] BETWEEN GETDATE() AND DATEADD(week, 52, GETDATE())
GROUP BY
    CONVERT(nchar(4), DATEPART(year, [date]))
     + '-' + 
    CONVERT(nchar(2), DATEPART(wk, [date]))
WITH ROLLUP

数据以行而不是列的形式返回。数据库查询以这种方式工作,尝试将数据强制转换为动态列非常不切实际。你只能求助于Conrad所说的,或者使用动态sql(用while循环构建一个字符串)来做同样的事情。我不会这样做。

WITH ROLLUP只会添加另一行,其中'Week'= NULL,总和为'Count'。

答案 2 :(得分:1)

尝试每周报告

SELECT 
    FLOOR((DATEDIFF(DAY, 'YourStartDate', [DateColumn])) / 7) + 1 AS [Week], 
    CAST(CAST(DATEADD(WEEK, FLOOR((DATEDIFF(DAY, 'YourStartData', [DateColumn])) / 7), 'YourStartData') AS DATE) AS NVARCHAR(16)) + ' - ' + 
    CAST(CAST(DATEADD(DAY, FLOOR((DATEDIFF(DAY, 'YourStartData', [DateColumn])) / 7) * 7 + 6, 'YourStartData') AS DATE) AS NVARCHAR(16)) AS [Range], 
    COUNT(*) AS [TotalPurchased] 
FROM 
    [Table] WITH (NOLOCK) 
GROUP BY 
    FLOOR((DATEDIFF(DAY, 'YourStartDate', [DateColumn])) / 7) 
ORDER BY 
    FLOOR((DATEDIFF(DAY, 'YourStartDate', [DateColumn])) / 7) + 1 

结果将显示: 周数,范围(来自YourStartDate - 最多7天)和TotalPurchased。您也可以使用CAST(GETDATE()作为日期)作为参数而不是'YourStartDate'

答案 3 :(得分:0)

这只是您可以根据自己的意愿定制的另一种解决方案。

请注意,没有可变的列集。也许你应该重新质疑你的要求。使用变量列集返回结果不会影响执行计划缓存,它可能会在需要该结果的应用程序中表示数据库映射的问题。

嗯,这就是......

DECLARE @start datetime = '2012-6-1'

;WITH tally AS (
  SELECT TOP 52 -- change this if you want more or less than a year of data
    N = row_number() OVER(ORDER BY (SELECT 0)) - 1
  FROM master.dbo.syscolumns sc1)
,weekSums AS (
  SELECT 
    N,
    val = 
      (SELECT COUNT(*) -- Can be ISNULL(SUM(amount), 0) or something else
      FROM #myreport
      WHERE [date] > DATEADD(dd, N * 7, @start) AND at <= DATEADD(dd, (N + 1) * 7, @start))
  FROM tally)
SELECT
  totalPurchased = (SELECT sum(val) FROM weekSums),
  week1 = (SELECT val FROM weekSums WHERE N = 0),
  week2 = (SELECT val FROM weekSums WHERE N = 1),
  week3 = (SELECT val FROM weekSums WHERE N = 2),
  ...
  week52 = (SELECT val FROM weekSums WHERE N = 51)

您可以查看星期编号的计数,使用weekSums进行总结,最后选择以显示结果。它很快,可以保存和重复使用执行计划(例如,当包装在SP中时)。

注意:此脚本可以使用动态合并/填充完成,但如果不是绝对必要,我不支持这种方法。

相关问题